2010-12-01 8 views
3

Je crée un programme qui peut indexer de nombreux fichiers texte dans un dossier différent. Donc, cela signifie que chaque dossier contenant des fichiers texte est indexé et que son index est stocké dans un autre dossier. donc cet autre dossier agit comme un index universel de tous les fichiers de mon ordinateur. et j'emploie lucene pour réaliser ceci parce que Lucene a soutenu complètement la mise à jour incrémentielle. C'est le code source dans lequel je l'utilise pour l'indexation.problème avec la mise à jour incrémentielle dans lucene

public class SimpleFileIndexer { 


public static void main(String[] args) throws Exception { 

    int i=0; 
    while(i<2) { 
    File indexDir = new File("C:/Users/Raden/Documents/myindex"); 
    File dataDir = new File("C:/Users/Raden/Documents/indexthis"); 
    String suffix = "txt"; 

    SimpleFileIndexer indexer = new SimpleFileIndexer(); 

    int numIndex = indexer.index(indexDir, dataDir, suffix); 

    System.out.println("Total files indexed " + numIndex); 
    i++; 
    Thread.sleep(1000); 

    } 
} 


private int index(File indexDir, File dataDir, String suffix) throws Exception { 
    RAMDirectory ramDir = new RAMDirectory();   // 1 
    @SuppressWarnings("deprecation") 
    IndexWriter indexWriter = new IndexWriter(
      ramDir,         // 2 
      new StandardAnalyzer(Version.LUCENE_CURRENT), 
      true, 
      IndexWriter.MaxFieldLength.UNLIMITED); 
    indexWriter.setUseCompoundFile(false); 
    indexDirectory(indexWriter, dataDir, suffix); 
    int numIndexed = indexWriter.maxDoc(); 
    indexWriter.optimize(); 
    indexWriter.close(); 

    Directory.copy(ramDir, FSDirectory.open(indexDir), false); // 3 

    return numIndexed; 
} 


private void indexDirectory(IndexWriter indexWriter, File dataDir, String suffix) throws IOException { 
    File[] files = dataDir.listFiles(); 
    for (int i = 0; i < files.length; i++) { 
     File f = files[i]; 
     if (f.isDirectory()) { 
      indexDirectory(indexWriter, f, suffix); 
     } 
     else { 
      indexFileWithIndexWriter(indexWriter, f, suffix); 
     } 
    } 
} 

private void indexFileWithIndexWriter(IndexWriter indexWriter, File f, String suffix) throws IOException { 
    if (f.isHidden() || f.isDirectory() || !f.canRead() || !f.exists()) { 
     return; 
    } 
    if (suffix!=null && !f.getName().endsWith(suffix)) { 
     return; 
    } 
    System.out.println("Indexing file " + f.getCanonicalPath()); 

    Document doc = new Document(); 
    doc.add(new Field("contents", new FileReader(f)));  
doc.add(new Field("filename", f.getCanonicalPath(), Field.Store.YES, Field.Index.ANALYZED)); 
    indexWriter.addDocument(doc); 
} } 

ce qui est le code source que j'utilise pour rechercher l'index créé Lucene-

public class SimpleSearcher { 

public static void main(String[] args) throws Exception { 

    File indexDir = new File("C:/Users/Raden/Documents/myindex"); 
    String query = "revolution"; 
    int hits = 100; 

    SimpleSearcher searcher = new SimpleSearcher(); 
    searcher.searchIndex(indexDir, query, hits); 

} 

private void searchIndex(File indexDir, String queryStr, int maxHits) throws Exception { 

    Directory directory = FSDirectory.open(indexDir); 

    IndexSearcher searcher = new IndexSearcher(directory); 
    @SuppressWarnings("deprecation") 
    QueryParser parser = new QueryParser(Version.LUCENE_30, "contents", new StandardAnalyzer(Version.LUCENE_CURRENT)); 
    Query query = parser.parse(queryStr); 

    TopDocs topDocs = searcher.search(query, maxHits); 

    ScoreDoc[] hits = topDocs.scoreDocs; 
    for (int i = 0; i < hits.length; i++) { 
     int docId = hits[i].doc; 
     Document d = searcher.doc(docId); 
     System.out.println(d.get("filename")); 
    } 

    System.out.println("Found " + hits.length); 

} 

} 

le problème que j'ai maintenant que le programme d'indexation j'ai créé ci-dessus semblent ne peut faire aucun mise à jour incrémentielle. Je veux dire que je peux rechercher un fichier texte mais seulement pour le fichier qui existait dans le dernier dossier auquel j'ai déjà indexé, et l'autre dossier précédent que j'avais déjà indexé semble manquer dans le résultat de la recherche et ne s'est pas affiché . pouvez-vous me dire ce qui s'est mal passé dans mon code? Je voulais juste avoir une fonction de mise à jour incrémentielle dans mon code source. Donc, en substance, mon programme semble remplacer l'index existant par le nouveau au lieu de le fusionner.

merci bien

Répondre

1

Directory.copy() Ecrase le répertoire de destination, vous devez utiliser IndexWriter.addIndexes() pour fusionner les nouveaux indices de répertoire dans le principal.

Vous pouvez également rouvrir l'index principal et y ajouter des documents directement. Un RAMDirectory n'est pas nécessairement plus efficace que les paramètres de tampon et de facteur de fusion correctement réglés (voir docs IndexWriter).

Mise à jour: au lieu de Directory.copy() vous devez ouvrir ramDir pour la lecture et l'écriture et indexDir pour appeler .addIndexes sur l'écrivain indexDir et transmettre le lecteur ramDir. Alternativement, vous pouvez utiliser .addIndexesNoOptimize et le passer directement au ramDir (sans ouvrir un lecteur) et optimiser l'index avant de le fermer.

Mais, en réalité, il est probablement plus facile d'ignorer RAMDir et d'ouvrir un writer sur indexDir en premier lieu. Cela facilitera également la mise à jour des fichiers modifiés.

Exemple

private int index(File indexDir, File dataDir, String suffix) throws Exception { 
    RAMDirectory ramDir = new RAMDirectory(); 
    IndexWriter indexWriter = new IndexWriter(ramDir, 
     new StandardAnalyzer(Version.LUCENE_CURRENT), true, 
     IndexWriter.MaxFieldLength.UNLIMITED); 
    indexWriter.setUseCompoundFile(false); 
    indexDirectory(indexWriter, dataDir, suffix); 
    int numIndexed = indexWriter.maxDoc(); 
    indexWriter.optimize(); 
    indexWriter.close(); 


    IndexWriter index = new IndexWriter(FSDirectory.open(indexDir), 
     new StandardAnalyzer(Version.LUCENE_CURRENT), true, 
     IndexWriter.MaxFieldLength.UNLIMITED); 
    index.addIndexesNoOptimize(ramDir); 
    index.optimize(); 
    index.close(); 

    return numIndexed; 
} 

Mais, tout cela est très bien aussi:

private int index(File indexDir, File dataDir, String suffix) throws Exception { 

    IndexWriter index = new IndexWriter(FSDirectory.open(indexDir), 
     new StandardAnalyzer(Version.LUCENE_CURRENT), true, 
     IndexWriter.MaxFieldLength.UNLIMITED); 

    // tweak the settings for your hardware 
    index.setUseCompoundFile(false); 
    index.setRAMBufferSizeMB(256); 
    index.setMergeFactor(30); 

    indexDirectory(index, dataDir, suffix); 

    index.optimize(); 
    int numIndexed = index.maxDoc(); 
    index.close(); 

    // you'll need to update indexDirectory() to keep track of indexed files 
    return numIndexed; 
} 
+0

Je suis une perte de peu here.can que vous venez de me montrer quelle ligne qui ont besoin d'être changé? Je veux dire, pouvez-vous l'éditer pour que ce soit clair pour moi. :-) – jacobian

+0

bien oui merci beaucoup. :-) – jacobian

Questions connexes