1

これまでのところ、Lucene は素晴らしいと思いますが、LIKE と同等の検索を複製する際にいくつか問題があります。

私が取り組んでいるアプリケーションでは、「簡易」(LIKE) 検索と高度な (全文) 検索のオプションが必要です。データはユーザーベース (名前、場所など) であるため、大量のテキストではありません。

以前は、用語をワイルドカードで囲み、db フィールド名を連結する SQL クエリを作成するだけでした。私のアプリケーションでは、ユーザー データの単純な検索のために lucene をバイパスしてそれを行うことができますが、lucene を使用すると便利です。

正規表現検索を試しました

var query = QueryParser.Escape(_query);
var search = new RegexQuery(new Term("name",string.Concat(".*", _query, ".*")));

ただし、それらは 1 つの列でのみ機能します。

私が持っていたアイデアの 1 つは、各フィールドをトークン化して、全文検索に似たものを生成することでした。

名前: ポール

だから私は次の名前フィールドを作成します...

ポール・パウ・パ・アウル・ウル・アウ

これは、LIKE SQL 検索で lucene を使用するポイントを無効にしますか? それは実際に私が望む結果を生み出すでしょうか?

この問題を解決する最善の方法は何でしょうか?

編集:

この質問のコードを少し変更します。

長さの違いを最小限に抑えるために、単語の境界で文字列を 2 つの文字列に分割するエレガントな方法

このトークナイザーを作成するには:

    private IEnumerable<string> Tokeniser(string _item)
    {
        string s = _item;

        const int maxPrefixLength = 10;
        const int maxSuffixLength = 10;
        const int minStemLength = 1;

        var tokens = new List<string>();


        for (int prefixLength = 0; (prefixLength + minStemLength <= s.Length) && (prefixLength <= maxPrefixLength); prefixLength++)
            for (int suffixLength = 0; (suffixLength + prefixLength + minStemLength <= s.Length) && (suffixLength <= maxSuffixLength); suffixLength++)
            {
                string prefix = s.Substring(0, prefixLength);
                string suffix = s.Substring(s.Length - suffixLength);
                string stem = s.Substring(prefixLength, s.Length - suffixLength - prefixLength);

                if (prefix.Length > 1)
                    if (!tokens.Contains(prefix))
                        tokens.Add(prefix);

                if (suffix.Length > 1)
                    if (!tokens.Contains(suffix))
                        tokens.Add(suffix);

                if (stem.Length > 1)
                    if (!tokens.Contains(stem))
                        tokens.Add(stem);
            }

        return tokens;
    }

検索結果は、LIKE 検索と同等のものを提供します。私の「ユーザー」テーブルのサイズは 9000 エンティティしかないので、少なくとも私にとっては、これが私のニーズに合うかもしれません。

これを行うことの欠点はありますか (はるかに大きなルセン インデックスを除いて?)

4

1 に答える 1

1

文字ベースの n-gram (NGramTokenizer、NGramTokenFilter、EdgeNGramTokenizer、および EdgeNGramTokenFilter は、必要な機能を提供する必要があります。

于 2012-07-28T12:29:07.733 に答える