Использование Lucene для поиска адресов электронной почты


5

Я хочу использовать Lucene (в частности, Lucene.NET) для поиска доменов адресов электронной почты.

E.g. Я хочу найти «@ gmail.com», чтобы найти все письма, отправленные на адрес gmail.

Выполнение запроса Lucene для «*@gmail.com» приводит к ошибке, звездочки не могут быть в начале запросов. Выполнение запроса для «@ gmail.com» не возвращает никаких совпадений, поскольку «[email protected]» рассматривается как целое слово, и вы не можете искать только части слова.

Как я могу это сделать?

10

Никто не дал удовлетворительного ответа, поэтому мы начали разбирать документацию Lucene и обнаружили, что мы можем это сделать, используя пользовательские анализаторы и токенизаторы.

Ответ: Создать WhitespaceAndAtSymbolTokenizer и WhitespaceAndAtSymbolAnalyzer, а затем воссоздать индекс с помощью этого анализатора. Когда вы это сделаете, поиск «@ gmail.com» вернет все адреса gmail, потому что это рассматривается как отдельное слово благодаря только что созданному Tokenizer.

Вот исходный код, это на самом деле очень просто:

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

Вот оно! Теперь вам просто нужно перестроить свой индекс и выполнить все поиски с помощью этого нового анализатора. Например, писать документы в индексе:

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

Performing поиски должны использовать анализатор, а также:

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

Я также передал токенизатор через фильтр LowerCaseFilter, или, возможно, настроенный фильтр LowerCaseFilter, который будет содержать только строковый токен @ GmAil.COM 07 май. 142014-05-07 06:33:45


5

Я вижу у вас есть решение, но мой бы избежать этого и добавили поле к индексам, которые вы индексируете, называется email_domain, в которые я бы добавил обработанный домен адреса электронной почты. Это может показаться глупым, но объем хранения, связанный с этим, довольно минимален. Если вам кажется, что вы любите, скажите, что в каком-то домене было много поддоменов, вы могли бы вместо этого создать поле, в которое переместился домен, поэтому вы бы сохранили com.gmail, com.company.department или ae.eim, чтобы вы могли найти все связанные с Объединенными Арабскими Эмиратами адреса с префиксом «ae».


0

Вы могли бы отдельное поле, которое индексирует адрес электронной почты, наоборот: Index «[email protected]» как «[email protected]» Что позволяет сделать запрос для «[email protected]

  0

Хмм. Это звучит очень хаки. 05 окт. 082008-10-05 21:15:13


2

Там также setAllowLeadingWildcard

Но будьте осторожны . Это может привести к высокой производительности (поэтому по умолчанию она отключена). Возможно, в некоторых случаях это было бы легким решением, но я бы предпочел использовать обычную Tokenizer, как указано в Judah Himango.