Lucene: Suche nach mehreren Feldern mit Standardoperator = AND

8

Damit Benutzer über mehrere Felder mit Lucene 3.5 suchen, ich derzeit eine QueryParser für jedes Feld auf eine DisjunctionMaxQuery . Dies funktioniert gut, wenn mit OR als Standard-Operator, aber ich mag jetzt den Standard-Operator ändern und genauere (und weniger) Ergebnisse zu erhalten.

Problem ist, dass queryParser.setDefaultOperator(QueryParser.AND_OPERATOR) viele Dokumente nicht enthält, da alle Begriffe in mindestens einem Feld sein müssen.

Zum Beispiel sollten Sie die folgenden Daten für ein Dokument: Titelfeld = „Programmiersprachen“, Körper Feld = „Java, C ++, PHP“. Wenn ein Benutzer für Java-Programmierung dieses bestimmte Dokument in den Ergebnissen enthalten würde, nicht suchen war, da der Titel noch der Körper Feld alle Begriffe in der Abfrage enthält, obwohl kombinierten sie tun. Ich möchte, dass dieses Dokument für die obige Abfrage zurückgegeben wird, nicht jedoch für die Abfrage HTML-Programmierung .

Ich habe ein Catchall-Feld in Betracht gezogen, aber ich habe ein paar Probleme damit. Erstens enthalten Benutzer häufig Feldbegriffe in ihren Abfragen (Autor: Rechnung), was mit einem Catch-Feld nicht möglich ist. Außerdem markiere ich bestimmte Felder mit FastVectorHighlighter, die erfordern, dass sie indiziert und gespeichert werden. Also würde ich durch Hinzufügen eines Catch-Felds die meisten der gleichen Daten zweimal indizieren müssen, was zeit- und platzaufwendig ist.

Irgendwelche Ideen?

    
Chris Davi 17.12.2012, 00:33
quelle

3 Antworten

6

Ich denke, ich hätte etwas mehr Nachforschungen anstellen sollen. Stellt sich heraus MultiFieldQueryParser bietet das genaue Funktionalität, nach der ich gesucht habe. Aus irgendeinem Grund habe ich für jedes Feld, das ich so suchen wollte, einen QueryParser erstellt:

%Vor%

Dies würde zu einer Abfrage wie folgt führen:

%Vor%

... was ich nicht gesucht habe. Jetzt erstelle ich einen einzelnen MultiFieldQueryParser wie folgt:

%Vor%

Dies gibt mir die Suchanfrage, nach der ich gesucht habe:

%Vor%

Danke an @seeta und @femtoRgon für die Hilfe!

    
Chris Davi 17.12.2012, 22:10
quelle
2

Vielleicht brauchen Sie eine Kombination aus Booleschen Abfragen, die die verschiedenen Kombinationen von Feldern und Begriffen erfassen. In Ihrem gegebenen Beispiel könnte die Abfrage -

lauten

(Titel: Java UND Körper: Programmierung) ODER (Titel: Programmierung UND Körper: Java).

Ich weiß nicht, ob es eine vorhandene Query-Klasse gibt, die das automatisch für Sie generiert, aber ich denke, das sollte die ultimative Abfrage sein, die auf dem Index ausgeführt wird.

    
Seeta Somagani 17.12.2012 02:41
quelle
0

Sie möchten in der Lage sein, mehrere Felder mit demselben Satz von Begriffen zu durchsuchen, dann die Frage aus Ihrem Kommentar:

%Vor%

Möglicherweise nicht die beste Implementierung.

Sie erhalten effektiv entweder die Punktzahl aus dem Titel oder die Punktzahl aus dem Text für den kombinierten Satz von Begriffen. Der Fall, dass Sie Java im Titel und Programmierung im Körper getroffen haben, würde ca. gegeben werden. Gleiches Gewicht wie ein Treffer auf Java im Körper und kein Treffer beim Programmieren.

Ich denke, eine besser strukturierte Abfrage wäre:

%Vor%

Dies ist für mich sinnvoller, da Sie möchten, dass die Dismax-Abfragen das Ergebnis bei mehreren Abfragen desselben Begriffs (in verschiedenen Feldern) begrenzen, aber Sie möchten, dass das Scoring für Treffer zu unterschiedlichen Begriffen wächst, glaube ich.

Wenn diese Art von Abfragestruktur bessere Ergebnisse erzielt, können die Ergebnisse auf eine bestimmte Mindestpunktzahl begrenzt werden (ein Prozentsatz der zurückgegebenen maximalen Punktzahl anstelle eines einfachen hartcodierten Werts), um zu schwache Ergebnisse zu vermeiden gesehen werden.


Ich würde auch immer noch nicht alle Felder indizieren. Es ist eine Implementierung, die ich zuvor benutzt habe, während ich sowohl das spezifische Feld als auch das Catchall-Feld indiziert habe, was sowohl allgemeine Abfragen als auch spezifische Einzelfeld-Abfragen erlaubt. Der Index-Speicher ist für nicht ausgelagerte Begriffe eher schlank und wird im Allgemeinen die Performance verbessern, wenn Sie große, komplizierte Abfragen erstellen müssen, um diese nicht zu ersetzen.

Wenn Sie wirklich sicher sein wollen, dass nur wenig Speicherplatz benötigt wird, können Sie TermVectors sogar für dieses Feld deaktivieren:

%Vor%

Obwohl ich nicht weiß, wie viel Unterschied das wirklich machen würde.

    
femtoRgon 17.12.2012 07:50
quelle

Tags und Links