Elasticsearch 精确搜索与模糊搜索

Elasticsearch exact search with fuzzy search

我有一个索引,其中包含公司名称、公司的缩写以及公司业务的描述(索引架构如下)。本文档中的一个元素示例是:

{
  "abbreviation": "APPL",
  "name": "Apple",
  "description": "Computer software and hardware"
}

通常用户在搜索文档时会输入 abbreviation。有时他们可能会错误地输入这个,而 elasticsearch 在这种情况下效果很好。然而,大多数时候用户会准确地输入缩写,虽然他们会在响应的顶部获得最佳匹配,但一些低分(大于 0)的垃圾会回来。我试过在查询中摆弄 min_score 但很难选择这个参数,因为分数波动很大。

有没有办法去掉那些与 abbreviation 字段不完全匹配但仍然有模糊匹配作为备份的文档,以防完全匹配或用户搜索其他字段(例如 namedescription) 没有找到?

这里有几个例子:

  1. 仅查询 AAPL 会产生 3 个结果,这两个与查询完全匹配,因此得分相当高,但 ADP 仍然有些相似,但显然不是用户所拥有的搜索。
{
  "abbreviation": "APPL",
  "name": "Apple, Inc.",
  "description": "Computer software and hardware"
},
{
  "abbreviation": "APPL",
  "name": "Apple, Inc.",
  "description": "Computer software and hardware"
},
{
  "abbreviation": "ADP",
  "name": "Automatic Data Processing, Inc",
  "description": "Computer software and hardware"
}
  1. 查询 Apple,我们再次获得超级相关的前几个条目,但随后出现了一些其他公司名称。
{
  "abbreviation": "APPL",
  "name": "Apple, Inc.",
  "description": "Computer software and hardware"
},
{
  "abbreviation": "APPL",
  "name": "Apple, Inc.",
  "description": "Computer software and hardware"
},
{
  "abbreviation": "CSCO",
  "name": "AppDynamics (Cisco subsidiary)",
  "description": "Computer software"
}

文档的架构:

{
  "settings": {
    "index": {
      "requests.cache.enable": true
    }
  },
  "mappings": {
    "properties": {
      "abbreviation_and_name": {
        "type": "text",
        "boost": 2
      },
      "abbreviation": { "type": "text", "copy_to": "abbreviation_and_name", "boost": 20 },
      "name": { "type": "text", "copy_to": "abbreviation_and_name" },
      "description": { "type": "text" }
    }
  }
}

首先,我可能会质疑为什么在搜索AAPL时要带回以下文件:

{
  "abbreviation": "ADP",
  "name": "Automatic Data Processing, Inc",
  "description": "Computer software and hardware"
}

其次,我建议从索引映射中删除提升标准,建议在查询级别提升。

但总的来说,我相信您可能只需要一个 OR 查询:

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "abbreviation": {
              "query": "AAPL",
              "boost": 2
            }
          }
        },
        {
          "multi_match": {
            "query": "AAPL",
            "fields": ["name", "description"],
            "fuzziness": "AUTO"
          }
        }
      ]
    }
  }
}

这可能不会像您描述的那样产生准确的结果,但我相信这对于您的用例来说应该很好用。