【问题标题】:Autocomplete matching in Elastic SearchElastic Search 中的自动完成匹配
【发布时间】:2016-01-05 06:50:35
【问题描述】:

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

我正在尝试在此字段的搜索中构建自动完成功能,以便 D12 的查询可能匹配 D12D120D121、...、D1210 等。

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

"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"
}

这意味着为D1234 编制索引的ngram 是D1D12D123D1234

要查询这个我做如下:

"query": {
  "bool": {
    "should": {
      "match": {
        "identifier": {
          "query": "D12",
          "fuzziness": 0
        }
      }
    }
  }
}

这会从最长到最短返回结果,因此D12 会出现在结果的末尾。我将如何确保最短的标识符具有最高的相关性分数?

我的猜测是D12 查询与 ngram 匹配,如下所示:[{D12}, {D12}3, {D12}34] 和弹性搜索“哦,太好了,3 个匹配!”而不是 D12 结果将给出的 1 [{D12}]

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

任何帮助将不胜感激。

【问题讨论】:

  • 你用的是什么版本的ES?
  • 解决方案有效吗?
  • 嘿伙计,对不起,我还没有机会实现它并自己尝试一下。它会适用于其他bool 条件还是会覆盖这些条件?
  • 没问题,我几乎可以肯定它可以在不同的布尔条件下工作,但是如果您可以发布完整的查询,我可以对其进行测试并确保 100%
  • 它很酷的芽,我很快就会看看它

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


【解决方案1】:

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

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

您需要这样做,因为如果您直接在identifiersort,那么您将获得相同的结果,因为由于edge ngram filter,所有这些都将具有2 个字母标记。之后,这会给你想要的结果

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

希望这会有所帮助!

【讨论】:

  • 嘿伙计,再次感谢您的回答。当我只想查询这个字段但在合并其他查询时完全覆盖相关性分数时,这很有效。不确定我能否按照我的要求沿着 _script 排序路径。
  • 还只是想我会提到其他任何人,在较新版本的 ES 中默认禁用内联脚本(我使用的是 ES 2.1)。您可以启用此功能。或将脚本创建为.groovy 文件并将其放在您的/config/scripts/ 目录中。
猜你喜欢
  • 1970-01-01
  • 2022-11-30
  • 2015-07-13
  • 1970-01-01
  • 2021-02-17
  • 2021-02-20
  • 2023-01-13
  • 2011-07-18
  • 2021-01-23
相关资源
最近更新 更多