2013-07-19 7 views
6

Ich habe eine unscharfe Suche mit Lucene 4.3.1 durchgeführt, aber ich bin nicht mit dem Ergebnis zufrieden. Ich möchte eine Reihe von Ergebnissen angeben, die zurückgegeben werden sollten. Wenn ich zum Beispiel 10 Ergebnisse haben möchte, sollte es die 10 besten Treffer zurückgeben, egal wie schlecht sie sind. Meistens gibt es nichts zurück, wenn das Wort, nach dem ich suche, sich sehr von allem im Index unterscheidet. Wie kann ich mehr/unschärfere Ergebnisse erzielen?unscharfe Suche mit Lucene

Hier ist der Code, den ich habe:

public String[] luceneQuery(String query, int numberOfHits, String path) 
     throws ParseException, IOException { 

    File dir = new File(path); 
    Directory index = FSDirectory.open(dir); 

    query = query + "~"; 
    Query q = new QueryParser(Version.LUCENE_43, "label", analyzer) 
      .parse(query); 

    IndexReader reader = DirectoryReader.open(index); 
    IndexSearcher searcher = new IndexSearcher(reader); 

    Query fuzzyQuery = new FuzzyQuery(new Term("label", query), 2); 

    ScoreDoc[] fuzzyHits = searcher.search(fuzzyQuery, numberOfHits).scoreDocs; 
    String[] fuzzyResults = new String[fuzzyHits.length]; 

    for (int i = 0; i < fuzzyHits.length; ++i) { 
     int docId = fuzzyHits[i].doc; 
     Document d = searcher.doc(docId); 
     fuzzyResults[i] = d.get("label"); 
    } 

    reader.close(); 
    return fuzzyResults; 
} 

Antwort

4

großen bearbeiten Entfernungen sind nicht von FuzzyQuery in Lucene 4.x. mehr unterstützt Die aktuelle Implementierung von FuzzyQuery ist eine riesige Verbesserung der Leistung von der Lucene 3.x-Implementierung, unterstützt aber nur zwei Änderungen. Entfernungen größer als 2 Damerau-Levenshtein-Bearbeitungen gelten als selten sehr nützlich.

Nach dem FuzzyQuery documentation, wenn Sie wirklich höher bearbeiten Abstände haben muss:

Wenn Sie wirklich wollen, sollten Sie eine n-gram Indizierungstechnik (wie die Rechtschreibprüfung im Modul vorschlagen) statt.

Die starke Implikation ist, dass Sie neu überdenken sollten, was Sie erreichen möchten, und einen nützlicheren Ansatz finden.

+0

Danke, das hilft schon sehr. Ich versuche Einträge in einem rdf-Graphen (aus dbpedia) mit 1,7 Millionen Einträgen zu finden. Die Einträge, nach denen ich suche, können aus mehreren Wörtern bestehen, und in der Regel enthält die Abfrage viele Rechtschreibfehler. Ein weiteres Problem ist, dass Sie im Deutschen oft Wörter getrennt oder verkettet schreiben können. Deshalb brauche ich eine größere Entfernung. Kennst du einen geeigneteren Ansatz als das, was ich jetzt versuche? – tadumtada

+1

SpellChecker könnte ein guter Ansatz sein. [Metaphone] (http://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/language/Metaphone.html) kann auch sehr hilfreich im Umgang mit Rechtschreibfehlern sein. Soweit Wörter getrennt oder verkettet sind, würde es, wenn es ziemlich Standard ist, wahrscheinlich von [GermanAnalyzer] profitieren (http://lucene.apache.org/core/4_0_0/analyzers-common/org/apache/lucene/ Deutsch:. Englisch: www.mjfriendship.de/en/index.php?op...39&Itemid=32 Ich denke (ich kenne die Details der deutschen Stemming aber nicht), die einen StemFitler beinhalten, der mit so etwas umgehen sollte. – femtoRgon

+0

Es stinkt wirklich, dass sie die ineffiziente Art und Weise entfernt haben. SpellChecker ist keine Abfrage, also für APIs, die Abfragen als Argumente annehmen und die Lucene-Leser und -Sucher (Neo4j) verstecken, bleibt beim Upgrade eine verkrüppelte App übrig. –