2009-12-04 2 views
9

Ich habe einen relativ kleinen Index mit rund 4.000 Standorten. Unter anderem verwende ich es, um ein Autocomplete-Feld in einem Suchformular zu füllen.Wie werden Teilwortsuchen in Lucene.NET durchgeführt?

Mein Index enthält Dokumente mit einem Feld Location Werte wie

  • Ohio
  • Dayton, Ohio
  • Dublin, Ohio
  • Columbus, Ohio
enthält

ich sein will Ich bin in der Lage, "ohi" einzutippen und alle diese Ergebnisse erscheinen zu lassen und im Moment gibt es nichts, bis ich das ganze Wort "ohio" eintippe.

Ich verwende Lucene.NET v2.3.2.1 und der relevante Teil meines Codes ist wie für die Einrichtung meiner Anfrage folgt ....

BooleanQuery keywords = new BooleanQuery(); 
QueryParser parser = new QueryParser("location", new StandardAnalyzer()); 
parser.SetAllowLeadingWildcard(true); 
keywords.Add(parser.Parse("\"*" + location + "*\""), BooleanClause.Occur.SHOULD); 
luceneQuery.Add(keywords, BooleanClause.Occur.MUST); 

Kurz gesagt, würde Ich mag an bekomme das funktioniert wie eine LIKE-Klausel ähnlich wie

SELECT * from Location where Name LIKE '%ohi%' 

Kann ich das mit Lucene tun?

Antwort

14

Diese Abfrage:

parser.Parse(query.Keywords.ToLower() + "*") 
+0

Das hat den Trick gemacht! Du hattest genau das, was ich brauchte. /GBT: werd !!! – JamieGaines

+3

Diese Antwort gibt nicht an, wie der endgültige Code aussehen sollte. Ich weiß nicht, wo ich das hinstellen soll? Welcher Typ ist "Abfrage"? Eine letzte Probe wäre großartig. – irperez

+0

In Java zumindest, sollten Sie Leerzeichen trimmen, wie die Abfrage "Test *" kompilieren wird, während "Test *" nicht – bcoughlan

0

es ist mehr eine Frage der Besetzung Ihres Index mit Teilwörtern an erster Stelle. Ihr Analysator muss die Teilschlüsselwörter in den Index bei der Analyse einfügen (und hoffentlich dabei auch niedrigere als vollständige Schlüsselwörter gewichten).

Lucene Index Lookup Bäume arbeiten von links nach rechts. Wenn Sie in der Mitte eines Schlüsselworts suchen möchten, haben Sie es bei der Analyse getrennt. Das Problem ist, dass partielle Schlüsselwörter in der Regel Ihre Indexgrößen explodieren.

Menschen verwenden normalerweise wirklich kreative Analysatoren, die Wörter in Stammwörtern zerlegen (die Präfixe und Suffixe entfernen).

gehen Sie tiefer in Lucene zu verstehen. es ist gutes Zeug. :-)

1

Ja, das kann gemacht werden. Führender Platzhalter kann jedoch zu langsamen Abfragen führen. Überprüfen Sie die documentation. Wenn Sie die gesamte Zeichenfolge (z. B. "Dayton, Ohio") als einzelnes Token indizieren, werden die meisten Abfragen zu führenden Präfixabfragen degenerieren. Die Verwendung eines Tokenizers wie StandardAnalyzer (was Sie vermutlich bereits tun) wird die Notwendigkeit für führende Platzhalter verringern.

Wenn Sie aus Performancegründen keine führenden Präfixe haben möchten, können Sie Indexierungs-Ngrams ausprobieren. Auf diese Weise wird es keine führenden Platzhalterabfragen geben. Der Tokenizer ngram (der nur eine Länge von 4 annimmt) erzeugt Tokens für "Dayton Ohio" als "dayt", "ayto", "yton" und so weiter.

+0

Vielen Dank für die Antwort. Ich mache mir wegen der langsamen Abfragen noch keine Sorgen, denn ich würde gerne sehen, dass es zuerst funktioniert, bevor ich entscheide, ob es zu langsam ist oder nicht. Meine Standortliste sollte bei etwa 4.000 Dokumenten stabil bleiben, daher mache ich mir keine Sorgen, dass es noch größer wird. Wenn Sie sagen: "Ja, das kann getan werden." Könntest du ein wenig mehr ausarbeiten? Ich dachte, dass der Code, den ich oben gezeigt habe, tun sollte, was ich erwarte, aber es ist nicht. Irgendwelche Ideen, was ich falsch mache? – JamieGaines