4

大文字と小文字を区別せず、一部の文字のアクセントを無視して、単語の一部で検索しようとしています。出来ますか?デフォルトのトークナイザーを使用したngramでうまくいくはずですが、NESTでそれを行う方法がわかりません。

例: 「musiic」は「musiic」を含むレコードと一致する必要があります

私が使用している Elasticsearch のバージョンは 1.9 です。

私はこのようにやっていますが、うまくいきません...

var ix = new IndexSettings();
        ix.Add("analysis",
            @"{
               'index_analyzer' : {
                          'my_index_analyzer' : {
                                        'type' : 'custom',
                                        'tokenizer' : 'standard',
                                        'filter' : ['lowercase', 'mynGram']
                          }
               },
               'search_analyzer' : {
                          'my_search_analyzer' : {
                                        'type' : 'custom',
                                        'tokenizer' : 'standard',
                                        'filter' : ['standard', 'lowercase', 'mynGram']
                          }
               },
               'filter' : {
                        'mynGram' : {
                                   'type' : 'nGram',
                                   'min_gram' : 2,
                                   'max_gram' : 50
                        }
               }
    }");
        client.CreateIndex("sample", ix);

ありがとう、

デビッド

4

1 に答える 1

3

短い答え

あなたが探しているのは、レーベンシュタイン距離アルゴリズムを使用して類似した単語を照合するファジークエリだと思います。

nGramsに関する長い回答

nGramフィルターは、定義された最小/最大範囲に基づいて、テキストを多くの小さなトークンに分割します。

たとえば、「music」クエリから、フィルタは次を生成します。 'mu', 'us', 'si', 'ic', 'mus', 'usi', 'sic', 'musi', 'usic', and 'music'

ご覧のとおりmusiic、これらのnGramトークンのいずれとも一致しません。

なぜnGrams

nGramsの利点の1つは、挿入時にすべての潜在的なサブ文字列が事前に生成されてインデックスが作成されるため、ワイルドカードクエリが大幅に高速化されることです(nGramsを使用するとクエリが数秒から15ミリ秒に高速化されます)。

nGramsがない場合、各文字列は、インデックス[O(1)]で直接検索されるのではなく、クエリ時に一致する[O(n ^ 2)]を検索する必要があります。擬似コードとして:

hits = []
foreach string in index:
    if string.substring(query):
        hits.add(string)
return hits

vs

return index[query]

これは、挿入を遅くし、より多くのストレージを必要とし、メモリ使用量を増やすという犠牲を払うことに注意してください。

于 2013-03-23T20:36:00.697 に答える