使用Lucene搜索电子邮件地址

时间:2008-08-20 22:44:18

标签: .net search lucene

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

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

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

我该怎么做?

4 个答案:

答案 0 :(得分: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);

答案 1 :(得分:5)

我看到你有你的解决方案,但是我本可以避免这种情况,并在你正在索引的文件中添加了一个名为email_domain的字段,我将在其中添加已解析的电子邮件地址域。这可能听起来很愚蠢,但与此相关的存储量非常小。如果您想要变得更有魅力,可以说某个域有很多子域,您可以改为生成反向域所在的字段,这样您就可以存储com.gmail,com.company.department或ae.eim,这样您就可以找到所有阿拉伯联合酋长国相关地址的前缀查询为'ae。'

答案 2 :(得分:2)

还有setAllowLeadingWildcard

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

答案 3 :(得分:0)

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