6

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

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

对“*@gmail.com”运行 Lucene 查询会导致错误,星号不能位于查询的开头。对“@gmail.com”运行查询不会返回任何匹配项,因为“foo@gmail.com”被视为一个完整的单词,您不能只搜索单词的一部分。

我怎样才能做到这一点?

4

4 回答 4

12

没有人给出令人满意的答案,因此我们开始研究 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);
于 2008-08-21T16:38:40.307 回答
6

我看到你有你的解决方案,但我的会避免这种情况,并在你正在索引的文档中添加一个名为 email_domain 的字段,我会在其中添加电子邮件地址的解析域。这听起来可能很愚蠢,但与此相关的存储量非常少。如果您想变得更高级,假设某个域有很多子域,则可以改为创建一个域,将反向域放入其中,这样您就可以存储 com.gmail、com.company.department 或 ae.eim,这样您就可以找到所有带有“ae”前缀查询的阿拉伯联合酋长国相关地址。

于 2008-08-22T21:07:01.620 回答
2

还有setAllowLeadingWildcard

But be careful. This could get very performance expensive (thats why it is disabled by default). Maybe in some cases this would be an easy solution, but I would prefer a custom Tokenizer as stated by Judah Himango, too.

于 2008-09-19T07:37:46.963 回答
0

您可以使用一个单独的字段来索引反向的电子邮件地址: Index 'foo@gmail.com' as 'moc.liamg@oof' 这使您可以查询“moc.liamg@*”

于 2008-09-17T14:13:41.083 回答