10

Elasticsearch 補完サジェスターを使用すると、1 単語のクエリに一致する複数単語の入力候補を返す際に問題が発生します。

構造例:

PUT /test_index/
{
   "mappings": {
      "item": {
         "properties": {
            "test_suggest": {
               "type": "completion",
               "index_analyzer": "whitespace",
               "search_analyzer": "whitespace",
               "payloads": false
            }
         }
      }
   }
}

PUT /test_index/item/1
{
   "test_suggest": {
      "input": [
         "cat dog",
         "elephant"
      ]
   }
}

作業クエリ:

POST /test_index/_suggest
{
    "test_suggest":{
        "text":"cat",
        "completion": {
            "field" : "test_suggest"
        }
    }
}

結果で

{
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "test_suggest": [
      {
         "text": "cat",
         "offset": 0,
         "length": 3,
         "options": [
            {
               "text": "cat dog",
               "score": 1
            }
         ]
      }
   ]
}

失敗したクエリ:

POST /test_index/_suggest
{
    "test_suggest":{
        "text":"dog",
        "completion": {
            "field" : "test_suggest"
        }
    }
}

結果で

{
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "test_suggest": [
      {
         "text": "dog",
         "offset": 0,
         "length": 3,
         "options": []
      }
   ]
}

「cat dog」に一致する作業クエリと同じ結果が期待されます。問題の内容と、失敗したクエリを機能させる方法について何か提案はありますか? 空白アナライザーの代わりに標準アナライザーを使用すると、同じ結果が得られます。上記の例のように、入力文字列ごとに複数の単語を使用したいと考えています。

4

1 に答える 1

14

補完サジェスタは、プレフィックスのサジェスタです。つまり、クエリを、与えられた入力の最初の数文字に一致させようとします。投稿したドキュメントを「犬」というテキストと一致させたい場合は、入力として「犬」を指定する必要があります。

PUT /test_index/item/1
{
   "test_suggest": {
      "input": [
         "cat dog",
         "elephant",
         "dog"
      ]
   }
}

私の経験では、一致する入力を指定する必要があるという制限により、補完サジェスターはプレフィックス マッチングを実装する他の方法よりも有用性が低くなります。私はこの目的のためにエッジ ngramが好きです。私は最近、ngram の使用に関するブログ記事を書きました

簡単な例として、使用できるマッピングを次に示します

PUT /test_index
{
   "settings": {
      "analysis": {
         "filter": {
            "edge_ngram_filter": {
               "type": "edge_ngram",
               "min_gram": 2,
               "max_gram": 20
            }
         },
         "analyzer": {
            "edge_ngram_analyzer": {
               "type": "custom",
               "tokenizer": "standard",
               "filter": [
                  "lowercase",
                  "edge_ngram_filter"
               ]
            }
         }
      }
   },
   "mappings": {
      "item": {
         "properties": {
            "text_field": {
               "type": "string",
               "index_analyzer": "edge_ngram_analyzer",
               "search_analyzer": "standard"
            }
         }
      }
   }
}

次に、次のようにドキュメントにインデックスを付けます。

PUT /test_index/item/1
{
   "text_field": [
      "cat dog",
      "elephant"
   ]
}

これらのクエリのいずれかがそれを返します。

POST /test_index/_search
{
    "query": {
        "match": {
           "text_field": "dog"
        }
    }
}

POST /test_index/_search
{
    "query": {
        "match": {
           "text_field": "ele"
        }
    }
}

POST /test_index/_search
{
    "query": {
        "match": {
           "text_field": "ca"
        }
    }
}

まとめたコードは次のとおりです。

http://sense.qbox.io/gist/4a08fbb6e42c34ff8904badfaaeecc01139f96cf

于 2015-04-20T17:28:31.640 に答える