2014-09-17 7 views
7

Es scheint, dass jedes Mal, wenn ich ein vorhandenes Dokument im Index aktualisiere (dasselbe Verhalten für delete/add), es nicht mit einer TermQuery gefunden werden kann. Hier ist ein kurzer Ausschnitt:Lucene kann Dokumente nach dem Update nicht finden

iw = neuer IndexWriter (Verzeichnis, Config);

Document doc = new Document(); 
doc.add(new StringField("string", "a", Store.YES)); 
doc.add(new IntField("int", 1, Store.YES)); 

iw.addDocument(doc); 

Query query = new TermQuery(new Term("string","a")); 

Document[] hits = search(query); 
doc = hits[0]; 
print(doc); 

doc.removeField("int"); 
doc.add(new IntField("int", 2, Store.YES)); 

iw.updateDocument(new Term("string","a"), doc); 

hits = search(query); 
System.out.println(hits.length); 
System.out.println("_________________"); 

for(Document hit : search(new MatchAllDocsQuery())){ 
    print(hit); 
} 

Dies erzeugt die folgende Ausgabe der Konsole:

stored,indexed,tokenized,omitNorms,indexOptions=DOCS_ONLY<string:a> 
stored<int:1> 
________________ 
0 
_________________ 
stored,indexed,tokenized,omitNorms,indexOptions=DOCS_ONLY<string:a> 
stored<int:2> 
________________ 

Es scheint, dass das Dokument (und nicht das neue Dokument) im Index nach dem Update, und durch die MatchAllDocsQuery zurückgegeben wird, kann aber nicht von einer TermQuery gefunden werden.

Vollbeispielcode verfügbar bei http://pastebin.com/sP2Vav9v

Auch dies geschieht nur (zweite Suche nicht funktioniert), wenn der Stringfield Wert Sonderzeichen enthält (zum Beispiel file:/F: /).

+1

Vermissen Sie nicht 'iw.commit()'? – mindas

+0

Ändert nichts. Ich habe es schon versucht. Außerdem öffnet die Suche jedes Mal einen neuen Leser vom Writer: DirectoryReader reader = DirectoryReader.open (iw, true); – Michael

+0

Ich scheine ein ähnliches Problem zu treffen. Welche Version von Lucene ist das? – carlspring

Antwort

4

Der Code, auf den Sie in Pastebin verwiesen haben, findet nichts, weil Ihr StringField nichts anderes als ein Stoppwort ist (a). Das Ersetzen von a durch etwas, das kein Stoppwort ist (z. B. ax), führt dazu, dass beide Suchen 1 Dokument zurückgeben.

würden Sie auch das richtige Ergebnis erzielen, wenn Sie StandardAnalyzer mit leeren Stoppwort-Satz zu konstruieren sind (CharArraySet.EMPTY_SET) noch noch a für StringField verwenden. Dies funktioniert jedoch nicht für file:/F:/. Die beste Lösung wäre, in diesem Fall StandardAnalyzer durch KeywordAnalyzer zu ersetzen.

+0

Ich dachte StringField wird nicht analysiert? Wie kommt es, dass die Aktualisierung diesen Effekt hat, aber das Einfügen eines neuen Dokuments nicht? – Michael

+0

'StringField' wird nicht analysiert, das ist richtig. Aber der Stoppwort-Filter wird immer noch angewendet - siehe 'StandardAnalyzer' Javadoc. Lucene im Action-Buch (Seite 120-121) sagt: "' StandardAnalyzer' enthält auch das Entfernen von Stoppwörtern ". In Bezug auf das Aktualisieren/Einfügen der Frage - ich bin mir nicht ganz sicher. Ich werde versuchen, Ergebnisse zu debuggen und zu veröffentlichen, wenn ich welche finde. – mindas

1

Ich könnte loswerden, indem ich mein Arbeitsverzeichnis nach allen Indexierungsoperationen neu erstellen: Erstellen Sie ein neues Verzeichnis nur für diese Indizierung Operationen namens "path_dir" zum Beispiel. Wenn Sie aktualisiert haben, rufen Sie die folgenden Vorgänge auf und führen Sie alle vorherigen Arbeiten erneut aus.

StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_46); 
FSDirectory dir; 
try { 
    // delete indexing files : 
    dir = FSDirectory.open(new File(path_dir)); 
    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_46, analyzer); 
    IndexWriter writer = new IndexWriter(dir, config); 
    writer.deleteAll(); 
    writer.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

Beachten Sie jedoch, dass dieser Weg sehr langsam ist, wenn Sie mit großen Datenmengen arbeiten.

+0

Wie ist das genau ein "Fix"? Löschen des Index ist absolut lächerlich! Was passiert, wenn Sie 10 000 000 Datensätze fünfmal aktualisieren müssen und Sie jedes Mal den Index löschen müssen ?! Das ist nicht akzeptabel. – carlspring

+0

Ich habe bereits am Ende meiner Antwort über Big Data kommentiert. Ich könnte meinen Code auf diese Weise in Ordnung bringen. Da ich keine großen Datenmengen bearbeite, war das kein Problem für mich. Wenn Michael auch kleine Daten hat, könnte es funktionieren. – balik

Verwandte Themen