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 アドレスが返されます。これは、先ほど作成したトークナイザーのおかげで別の単語として認識されるためです。

これがソースコードです。実際には非常に単純です。

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もあります

しかし、注意してください。これにより、パフォーマンスが非常に高くなる可能性があります (デフォルトで無効になっているのはそのためです)。場合によってはこれが簡単な解決策になるかもしれませんが、私はJudah Himangoが述べているように、カスタム Tokenizer を好むでしょう。

于 2008-09-19T07:37:46.963 に答える
0

メールアドレスを逆にインデックス付けする別のフィールドを作成できます。「foo@gmail.com」を「moc.liamg@oof」としてインデックス付けします。これにより、「moc.liamg@*」のクエリを実行できます。

于 2008-09-17T14:13:41.083 に答える