Używanie Lucene do wyszukiwania adresów e-mailowych


5

Chcę używać Lucene (w szczególności Lucene.NET) do wyszukiwania domen adresów e-mail.

E.g. Chcę wyszukać "@ gmail.com", aby znaleźć wszystkie wiadomości e-mail wysłane na adres Gmail.

Uruchomienie zapytania Lucene dla "*@gmail.com" powoduje błąd, a gwiazdki nie mogą być na początku zapytania. Uruchamianie zapytania dla "@ gmail.com" nie zwraca żadnych dopasowań, ponieważ "[email protected]" jest postrzegane jako całe słowo i nie można wyszukiwać tylko części wyrazu.

Jak mogę to zrobić?

10

Nikt nie udzielił zadowalającej odpowiedzi, więc zaczęliśmy szperać w dokumentacji Lucene i odkryliśmy, że możemy to zrobić za pomocą niestandardowych analizatorów i tokenizerów.

Odpowiedź jest następująca: utwórz WhitespaceAndAtSymbolTokenizer i WhitespaceAndAtSymbolAnalyzer, a następnie utwórz indeks za pomocą tego analizatora. Gdy to zrobisz, wyszukiwanie "@ gmail.com" zwróci wszystkie adresy w Gmailu, ponieważ jest to oddzielne słowo dzięki utworzonemu przez nas Tokenizerowi.

Oto kod źródłowy, to faktycznie bardzo prosta:

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); 
    } 
} 

To jest to! Teraz wystarczy przebudować swój indeks i wykonać wszystkie wyszukiwania przy użyciu tego nowego analizatora. Na przykład, aby zapisywać dokumenty do indeksu:

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

wyszukiwania sceniczne powinny używać analizatora, a także:

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

Mogę również przekazać tokenizator przez LowerCaseFilter lub niestandardowy LowerCaseFilter, który będzie tylko mały znacznik @ GmAil.COM 07 maj. 142014-05-07 06:33:45


5

widzę masz rozwiązanie, ale kopalnia byłoby uniknąć tego i dodaje pole do indeksowanych dokumentów o nazwie email_domain, do których dodałbym przeanalizowaną domenę adresu e-mail. To może zabrzmieć głupio, ale ilość pamięci związanej z tym jest całkiem minimalna. Jeśli masz ochotę stać się bardziej doświadczonym, powiedzmy, że niektóre domeny mają wiele subdomen, możesz zamiast tego utworzyć pole, w którym znajduje się odwrócona domena, więc możesz przechowywać com.gmail, com.company.department lub ae.eim, abyś mógł znaleźć wszystkie adresy powiązane Zjednoczone Emiraty Arabskie z zapytaniem prefiksowym "ae".


0

Mogłabyś oddzielna dziedzina, która indeksuje adres email odwrócona: Index „[email protected]” jako „[email protected]” która pozwala zrobić kwerendę dla „[email protected]*”

  0

Hmm. Brzmi naprawdę hackish. 05 paź. 082008-10-05 21:15:13


2

Istnieje również setAllowLeadingWildcard

Ale ostrożny. Może to bardzo kosztować wydajność (dlatego domyślnie jest wyłączona). Może w niektórych przypadkach byłoby to łatwe rozwiązanie, ale wolałbym niestandardowy Tokenizer, o którym wspomniał także Judah Himango.