Frage

Ich möchte Lucene (insbesondere Lucene.NET) verwenden, um nach E-Mail-Adressdomänen zu suchen.

Z.B.Ich möchte nach „@gmail.com“ suchen, um alle E-Mails zu finden, die an eine Gmail-Adresse gesendet wurden.

Das Ausführen einer Lucene-Abfrage für „*@gmail.com“ führt zu einem Fehler. Sternchen dürfen nicht am Anfang von Abfragen stehen.Wenn Sie eine Abfrage nach „@gmail.com“ ausführen, werden keine Treffer zurückgegeben, da „foo@gmail.com“ als ganzes Wort betrachtet wird und Sie nicht nur nach Wortteilen suchen können.

Wie kann ich das machen?

War es hilfreich?

Lösung

Niemand gab eine zufriedenstellende Antwort, also begannen wir, in der Lucene-Dokumentation herumzustöbern und stellten fest, dass wir dies mit benutzerdefinierten Analysatoren und Tokenizern erreichen können.

Die Antwort lautet:Erstellen Sie einen WhitespaceAndAtSymbolTokenizer und einen WhitespaceAndAtSymbolAnalyzer und erstellen Sie dann Ihren Index mit diesem Analysator neu.Sobald Sie dies tun, werden bei der Suche nach „@gmail.com“ alle Gmail-Adressen zurückgegeben, da es dank des soeben erstellten Tokenizers als separates Wort angezeigt wird.

Hier ist der Quellcode, eigentlich ist er ganz einfach:

class WhitespaceAndAtSymbolTokenizer : CharTokenizer
{
    public WhitespaceAndAtSymbolTokenizer(TextReader input)
        : base(input)
    {
    }

    protected override bool IsTokenChar(char c)
    {
        // Make whitespace characters and the @ symbol be indicators of new words.
        return !(char.IsWhiteSpace(c) || c == '@');
    }
}


internal class WhitespaceAndAtSymbolAnalyzer : Analyzer
{
    public override TokenStream TokenStream(string fieldName, TextReader reader)
    {
        return new WhitespaceAndAtSymbolTokenizer(reader);
    }
}

Das ist es!Jetzt müssen Sie nur noch Ihren Index neu erstellen und alle Suchvorgänge mit diesem neuen Analysator durchführen.So schreiben Sie beispielsweise Dokumente in Ihren Index:

IndexWriter index = new IndexWriter(indexDirectory, new WhitespaceAndAtSymbolAnalyzer());
index.AddDocument(myDocument);

Für die Durchführung von Suchen sollte auch der Analysator verwendet werden:

IndexSearcher searcher = new IndexSearcher(indexDirectory);
Query query = new QueryParser("TheFieldNameToSearch", new WhitespaceAndAtSymbolAnalyzer()).Parse("@gmail.com");
Hits hits = query.Search(query);

Andere Tipps

Ich sehe, dass Sie Ihre Lösung haben, aber meine hätte dies vermieden und den von Ihnen indizierten Dokumenten ein Feld namens email_domain hinzugefügt, in das ich die analysierte Domäne der E-Mail-Adresse eingefügt hätte.Es mag albern klingen, aber der damit verbundene Speicherplatz ist ziemlich gering.Wenn Sie Lust auf etwas Ausgefalleneres haben, sagen wir, dass eine Domain viele Subdomains hat, könnten Sie stattdessen ein Feld erstellen, in das die umgekehrte Domain eingefügt wird, sodass Sie com.gmail, com.company.department oder ae.eim speichern, damit Sie sie finden können Alle Adressen im Zusammenhang mit den Vereinigten Arabischen Emiraten mit der Präfixabfrage „ae“.

Gibt es auch setAllowLeadingWildcard

Aber sei vorsichtig.Dies könnte die Leistung erheblich beeinträchtigen (deshalb ist es standardmäßig deaktiviert).Vielleicht wäre dies in manchen Fällen eine einfache Lösung, aber ich würde einen benutzerdefinierten Tokenizer bevorzugen, wie von angegeben Judah Himango, zu.

Sie könnten ein separates Feld einfügen, das die umgekehrte E-Mail-Adresse indiziert:Index 'foo@gmail.com' als 'moc.liamg@oof', mit dem Sie eine Abfrage für "moc.liamg@*" durchführen können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top