【问题标题】:Elasticsearch exact search with fuzzy searchElasticsearch 精确搜索和模糊搜索
【发布时间】:2021-03-27 03:09:29
【问题描述】:

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

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

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

有没有办法摆脱与abbreviation 字段不完全匹配但仍有模糊匹配作为备份的文档,以防完全匹配或用户搜索其他字段(例如name 和@ 987654326@) 没有找到?

这里有几个例子:

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

【问题讨论】:

  • 嘿,也许您可​​以提供一些示例查询,您希望它们的行为如何?我想帮忙,但很难完全理解这个问题。
  • 好点。添加一些示例

标签: elasticsearch elasticsearch-5 elasticsearch-dsl


【解决方案1】:

首先,我可能会质疑为什么在搜索 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"
          }
        }
      ]
    }
  }
}

这可能不会产生您所描述的确切结果,但我相信这应该适合您的用例。

【讨论】:

  • 我最终使用prefix_search 解决了我的问题,它似乎非常适合我们的用例。我仍然赞成您的回复,因为看到 multi_match 的实际效果很有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
  • 2019-05-24
  • 2019-01-11
相关资源
最近更新 更多