2

私は次のアナライザーを持っています (スノーボールのセットアップ方法を微調整します):

  string_analyzer: {
    filter: [ "standard", "stop", "snowball" ],
    tokenizer: "lowercase"
  }

適用されるフィールドは次のとおりです。

  indexes :title, type: 'string', analyzer: 'string_analyzer'

  query do
    match ['title'], search_terms, fuzziness: 0.5, max_expansions: 10, operator: 'and'
  end

インデックスに title のレコードがありfoo barます。

検索foo barすると、結果に表示されます。

しかし、私が検索しfoobarてもそうではありません。

誰かが理由を説明できますか、可能であればどうすればそれを実現できますか?

foobarタイトル付きのレコードがあった場合、ユーザーが検索して結果として表示できるように、これの逆を機能させる方法を誰かが説明できますかfoo bar?

ありがとう

4

1 に答える 1

2

インデックスにあるトークンのみを検索できます。それでは、インデックスを作成しているものを見てみましょう。現在、lowercaseトークナイザー (文字以外の文字の文字列をトークン化し、小文字にする) を使用してから、フィルター (トークナイザーを使用していないため冗長) と フィルターを適用してstandardいます。standardstopsnowball

そのアナライザーを作成すると、次のようになります。

curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1'  -d '
{
   "settings" : {
      "analysis" : {
         "analyzer" : {
            "string_analyzer" : {
               "filter" : [
                  "standard",
                  "stop",
                  "snowball"
               ],
               "tokenizer" : "lowercase"
            }
         }
      }
   }
}
'

analyzeAPI を使用してテストします。

curl -XGET 'http://127.0.0.1:9200/test/_analyze?pretty=1&text=foo+bar&analyzer=string_analyzer' 

"foo bar"が項を生成し、項["foo","bar"]"foobar"生成することがわかります["foobar"]。そのため、現在のインデックス作成"foo bar"と検索は機能し"foobar"ません。

「内部」の単語を検索できるようにしたい場合は、単語を小さなトークンに分割する必要があります。これを行うには、ngramアナライザーを使用します。

したがって、テスト インデックスを削除します。

curl -XDELETE 'http://127.0.0.1:9200/test/?pretty=1' 

新しいアナライザーを指定します。

curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1'  -d '
{
   "settings" : {
      "analysis" : {
         "filter" : {
            "ngrams" : {
               "max_gram" : 5,
               "min_gram" : 1,
               "type" : "ngram"
            }
         },
         "analyzer" : {
            "ngrams" : {
               "filter" : [
                  "standard",
                  "lowercase",
                  "ngrams"
               ],
               "tokenizer" : "standard"
            }
         }
      }
   }
}
'

ここで、アナライザーをテストすると、次のようになります。

"foo bar" => [f,o,o,fo,oo,foo,b,a,r,ba,ar,bar]
"foobar"  => [f,o,o,b,a,r,fo,oo,ob,ba,ar,foo,oob,oba,bar,foob,ooba,obar,fooba,oobar]

したがって、インデックスを作成し、クエリを使用して"foo bar"検索すると、クエリはそれらのトークンのいずれかを検索するクエリになり、そのうちのいくつかはインデックスに存在します。"foobar"match

"wear the fox hat"残念ながら、 ( fo、 )とも重複しますafoobar共通のトークンが多いため、結果リストの上位に表示されますが、明らかに無関係な結果が得られます。

これは、minimum_should_matchパラメーターを使用して制御できます。たとえば、次のようになります。

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1'  -d '
{
   "query" : {
      "match" : {
         "my_field" : {
            "minimum_should_match" : "60%",
            "query" : "foobar"
         }
      }
   }
}
'

の正確な値はminimim_should_matchデータによって異なります。実験してみてください。

于 2013-02-08T09:43:43.367 に答える