2009-08-04 6 views
1

Ich verwende Lucene Search, um die Artikel zu erhalten, die zum Suchtext passen. Gibt es eine Möglichkeit, sie in aufsteigender Reihenfolge der Treffer im Artikel zu bekommen?Wie kann ich die Liste in LuceneSearch nach der Anzahl der Treffer bestellen?

Beispiel: Wenn mein Suchtext ist stack und in erster Artikel gibt es zwei Vorkommen des Wortes stack und in der zweiten Artikel gibt es drei Vorkommen von stack dann der zweite sollte an erster Stelle stehen und die erste sollte zweite kommen.

Eine Idee, wie kann ich es schaffen?

Unten ist der Code, den ich

List<LuceneSearchResult> searchResult = new List<LuceneSearchResult>(); 
LuceneSearchResult result; 
IndexReader reader = IndexReader.Open(INDEX_DIR); 
Searcher searcher = new IndexSearcher(reader); 
Analyzer analyzer = new StandardAnalyzer(); 

QueryParser parser = new QueryParser("Text", analyzer); 
//Text and Type are column name 

Query q = parser.Parse(string.Format("Text:{0} AND Type:{1}", finalText, type)); 
Hits hs = searcher.Search(q); 
ArrayList idList = new ArrayList(); 
for (int i = 0; i < hs.Length(); i++) 
{ 

    Document doc = hs.Doc(i); 
    result = new LuceneSearchResult(); 
    result.ID = doc.Get("ID"); 
    result.Type = doc.Get("Type"); 


    if (!idList.Contains(result.ID)) 
    { 
     searchResult.Add(result); 
     idList.Add(result.ID); 
    } 

} 
return searchResult.ToArray(); 

Antwort

2

Lucene sortiert die Dokumente nach Punkten. Für ein Dokument für eine bestimmte Abfrage gibt es mehrere Komponenten für die Bewertung. Einer von ihnen ist die Häufigkeit des Begriffs in dem abgefragten Feld. Für eine Suche nach einem einzelnen Begriff ist die Berechnung jedoch ziemlich einfach. Es ist proportional zur Quadratwurzel der Anzahl der Vorkommen des Ausdrucks im Feld normalisiert von Feldlänge. Dies könnte sein, wo Sie in Schwierigkeiten geraten.

Wenn Sie das Wort „Stapel“ und doc A hat 1 Vorkommen suchen, und doc B 2 Vorkommen hat, doc noch höher in den Ergebnissen Rang könnte, wenn die Feldlänge als die von doc B. wesentlich größer ist

Die gute Nachricht ist, dass Sie Feld Normalisierung deaktivieren können. Die schlechte Nachricht ist, dass Sie es tun müssen, bevor Sie indexieren, , es sei denn Sie über die Similarity-Klasse, um es immer auszumerzen, aber ich würde nicht empfehlen, es auf diese Weise zu tun. Um Normen zum Indexzeitpunkt zu deaktivieren, rufen Sie in Ihrem Indexierungscode Field.setOmitNorms (true) für das Field-Objekt auf, das Sie dem IndexWriter hinzufügen. In Ihrem Fall wäre das für das Feld "Text".

+0

Hallo KenE klingt das gut, aber wo implementiere ich Field.setOmitNorms (true) ?? –

+0

Sie würden es in Ihrem Indexierungscode nennen. – KenE

1

Lucene verwende sollte dies automatisch tun, aber es hängt in einem gewissen Teil auf, wie Sie Ihre Anfrage formulieren. Wenn Sie eine Abfrage mit mehr als einem Wort durchführen, sind diese standardmäßig ORd. Zum Beispiel, sagen, dass Ihre Abfrage so etwas wie dieses (Suche den Inhalt Feld) war:

contents:apples oranges 

Diese alle Seiten mit dem Begriff Äpfel oder Orangen in sie zurückkehren würde. Wenn eine Seite 50 Mal das Wort "Äpfel" enthält, aber kein Hinweis auf Orange, würde diese Seite immer noch höher rangieren als eine Seite, die nur einmal das Wort "Äpfel" und einmal "Orangen" enthielt.

Was möchten Sie wahrscheinlich zu tun ist, und Ihre Abfrage wie folgt:

contents:apples AND oranges 

Hinweis: Groß- und

Dies wird nur Seiten zurück, die sowohl das Wort „Äpfel“ und „Orangen“ haben in Es ist wahrscheinlich näher an dem, was Sie wollen.

Haben Sie einen Lese von Lucene - Query Parser Syntax für weitere Informationen darüber, wie mit Dan forumulate fragt

0

Ich bin damit einverstanden, dass dieses Standardverhalten des Lucene sein sollte. Wenn sich Ihre Implementierung nicht so verhält, fügen Sie bitte Details hinzu, damit wir Ihnen bei der Diagnose helfen können. Lucenes Similarity Klassendokumentation erklärt die Einzelheiten der Lucene-Bewertung, die für die Reihenfolge der Treffer verantwortlich ist.

+0

Ich benutze AND in der Abfrage bitte siehe oben Ich habe den Code, den ich verwende –

0

Auf den ersten Blick scheint Ihr Code wie erwartet zu funktionieren.
Können Sie uns ein Beispiel für einen finalText, Typ und die Ergebnisse zeigen?
Wenn ich unerwartete Ergebnisse erhalte, überprüfe ich normalerweise, welche Abfrage tatsächlich verwendet wurde (im Debug-Modus prüfe den Wert von q) und verwende diese Abfrage in Luke, um zu sehen, welche Ergebnisse es gibt.

In meinem Code verwende ich hits.Max statt hits.Length. Ich weiß nicht, was der Unterschied ist, aber es ist etwas, das ich bemerkt habe.

Auch, wenn der Rest Ihres Programms Sie sonst nicht diktiert, möchten Sie vielleicht die HashTable anstelle einer ArrayList für Ihre IdList auschecken, es ist in der Regel schneller.

0

Ich habe gegoogled herum und gefunden, dass Lucene das Suchergebnis in der Reihenfolge des Ergebnisses der Treffer auflistet, die nicht das Phänomen der Anzahl des Vorkommens der Phrase ist, sondern abhängig von verschiedenen Faktoren berechnet wird, und deshalb denke ich es Es ist nicht möglich, es von Lucene direkt zu bekommen, aber wenn Sie einen Weg finden, lassen Sie es mich bitte wissen.