使用Lucene搜索电子邮件地址


5

我想使用Lucene(特别是Lucene.NET)来搜索电子邮件地址域。

E.g.我想搜索“@ gmail.com”以查找发送到Gmail地址的所有电子邮件。

对“*@gmail.com”运行Lucene查询会导致错误,星号不能位于查询开始处。对“@ 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); 

执行搜索应该使用分析器,以及:

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 5月. 142014-05-07 06:33:45


5

我看到你有你的解决方案,但我会避免这一点,并添加一个字段到您要编入索引的文件称为email_domain,我将其中添加解析出的电子邮件地址域。这可能听起来很愚蠢,但与此相关的存储量非常少。如果你觉得自己变得更加奇特,比如说某个域名有许多子域名,那么你可以创建一个反向域名所在的域名,这样你就可以存储com.gmail,com.company.department或ae.eim,这样你就可以找到所有与阿拉伯联合酋长国有关的地址的前缀查询为'ae'。


0

,你可以单独的字段,索引的电子邮件地址逆转: 指数“[email protected]”为“[email protected]” 这使您可以为“[email protected]*”

做一个查询
  0

嗯。这听起来很骇人听闻。 05 10月. 082008-10-05 21:15:13


2

也有setAllowLeadingWildcard

但要小心。这可能会使性能非常昂贵(这就是为什么它在默认情况下被禁用)。也许在某些情况下,这将是一个简单的解决方案,但我更喜欢Judah Himango所述的自定义Tokenizer。