弹性搜索中的自动完成匹配

时间:2016-01-05 06:50:36

标签: search elasticsearch autocomplete full-text-search search-engine

所以我在弹性搜索中有一个identifier字符串字段,其中包含D123M1T23等值。

我正在尝试在搜索此字段时构建自动填充功能,以便D12的查询可能与D12D120D121,...,{匹配{1}}等等。

目前我已经构建了一个自定义边缘ngram滤波器和分析器:

D1210

在我的映射中,当索引时,我会在"filter": { "autocomplete_filter": { "type": "edgeNGram", "min_gram": 2, "max_gram": 10 } } "analyzer": { "autocomplete": { "type": "custom", "tokenizer": "whitespace", "filter": {"lowercase", "autocomplete_filter"} } } 字段中使用此字段:

identifier

这意味着为"identifier": { "type": "string", "analyzer": "autocomplete", "search_analyzer": "standard" } 编制索引的ngrams为D1234D1D12D123

要查询此信息,我的操作如下:

D1234

这会将结果从最长到最短返回,以便"query": { "bool": { "should": { "match": { "identifier": { "query": "D12", "fuzziness": 0 } } } } } 出现在结果的末尾。我如何确保最短的标识符具有最高的相关性分数?

我的猜测是D12查询匹配ngrams,如:D12和弹性搜索"哦,很棒,3场比赛!"而不是[{D12}, {D12}3, {D12}34]结果给出的1 [{D12}]

我猜一个解决方案可能不会与这些ngrams部分匹配,因此弹性搜索会看到D12两个结果,但排名[{D12}]高于D12,因为它匹配了1/2的ngrams而不是1/4。我不确定如何配置弹性搜索来提供此结果。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

您可以使用script based sorting执行此操作,但首先您需要将identifier字段映射为multi-fields,如下所示

"identifier": {
    "type": "string",
    "analyzer": "autocomplete",
    "search_analyzer": "standard",
    "fields": {
        "raw": {
            "type": "string",
            "index": "not_analyzed"
        }
    }
}

您需要执行此操作,因为如果您sort直接identifier,那么您将得到相同的结果,因为所有这些结果都会因{{2>字母标记而导致edge ngram filter 1}}。之后,这将给你想要的结果

{
  "query": {
    "bool": {
      "should": {
        "match": {
          "identifier": {
            "query": "D12",
            "fuzziness": 0
          }
        }
      }
    }
  },
  "sort": {
    "_script": {
      "script": "doc['identifier.raw'].value.length()",
      "order": "asc",
      "type": "number"
    }
  }
}

希望这会有所帮助!!