2010-12-01 6 views
3

Ich erstelle ein Programm, das viele Textdateien in verschiedenen Ordnern indizieren kann. Das heißt, jeder Ordner, der Textdateien enthält, wird indexiert und sein Index wird in einem anderen Ordner gespeichert. Dieser Ordner fungiert also als universeller Index aller Dateien auf meinem Computer. und ich verwende Lucene, um dies zu erreichen, weil Lucene vollständig inkrementelles Update unterstützt. Dies ist der Quellcode, in den ich ihn für die Indexierung verwende.Problem mit inkrementellem Update in 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); 
} } 

und dies ist der Quellcode, die ich für die Suche im Lucene-Index erstellt verwenden

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); 

} 

} 

das Problem, das ich jetzt habe, dass das Indexierungsprogramm I oben erstellt scheinen kann jeder nicht tun inkrementelles Update Ich meine, ich kann nach einer Textdatei suchen, aber nur nach der Datei, die im letzten Ordner existierte, in den ich bereits indizierte, und der andere vorherige Ordner, den ich bereits indiziert hatte, scheint im Suchergebnis zu fehlen und wurde nicht angezeigt . kannst du mir sagen, was in meinem Code schief gelaufen ist? Ich wollte nur inkrementelle Update-Funktion in meinem Quellcode haben. Im Wesentlichen scheint mein Programm den vorhandenen Index mit dem neuen Index zu überschreiben, anstatt ihn zu verschmelzen.

dank obwohl

Antwort

1

Directory.copy() das Zielverzeichnis überschreibt, müssen Sie IndexWriter.addIndexes() verwenden, um den neuen Verzeichnis-Indizes in das Haupt einer verschmelzen.

Sie können auch einfach den Hauptindex öffnen und Dokumente direkt hinzufügen. Ein RAMDirectory ist nicht notwendigerweise effizienter als richtig eingestellte Puffer- und Merge-Factor-Einstellungen (siehe IndexWriter Dokumente).

Update: statt Directory.copy() müssen Sie ramDir zum Lesen und indexDir zum Schreiben öffnen und .addIndexes auf dem indexDir Schriftsteller nennen und die ramDir Leser passieren. Alternativ können Sie .addIndexesNoOptimize verwenden und direkt ramDir übergeben (ohne einen Leser zu öffnen) und den Index vor dem Schließen optimieren.

Aber wirklich, es ist wahrscheinlich einfacher, einfach den RAMDir überspringen und öffnen Sie einen Schriftsteller auf indexDir in erster Linie. Erleichtert das Aktualisieren geänderter Dateien.

Beispiel

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; 
} 

Aber genau das ist auch in Ordnung:

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

Ich bin ein bisschen Verlust here.can Sie zeigen mir nur die Zeile, die geändert werden müssen? Ich meine, kannst du es bearbeiten, damit es für mich klar ist. :-) – jacobian

+0

naja ja danke dir aber sehr. :-) – jacobian