【问题标题】:elasticsearch match_phrase lists results containing my phrase before results that are exactly equal to my phraseelasticsearch match_phrase 在与我的短语完全相等的结果之前列出包含我的短语的结果
【发布时间】:2018-02-01 17:02:31
【问题描述】:

我正在尝试使用 ElasticSearch 对字符串字段执行短语搜索,但我并不真正理解返回结果的顺序。我有一个简单的“match_phrase”查询形式:

GET /MyIndex/_search
{
  "query": 
  { 
    "match_phrase": 
    {
      "FieldToSearch": "find this phrase" 
    }
  }
}

假设我的文档包含以下“FieldToSearch”值:["This is the way to find this phrase", "find this phrase", "find this phrase to win a prize"]。我希望它在其他 2 个结果之前返回 "find this phrase",因为它与我正在寻找的短语完全匹配。但是,我注意到它有时会首先列出 "find this phrase to win a prize" 之类的内容。有没有办法在包含完全匹配的结果之前返回“完全匹配”?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    短语“找到这个短语”对于索引中的文档来说太常见了。基本上每个文档都匹配这个搜索查询,并且相关性的微小差异是由于字段长度规范造成的。据我所知,字段长度范数是按分片计算的。因此,当索引的三个文档中的每一个都位于其自己的分片中时,您会看到稍微令人惊讶的搜索结果,其中文档与最短字段的相关性低于其他文档。您可以通过仅使用一个主分片创建索引来对其进行测试。在这种情况下,字段值为“find this phrase”的文档将获得最高分。您还可以通过禁用字段长度规范来为多个主分片获得相同的结果:

    PUT your_index/_mapping/your_type
    {
      "properties": {
        "FieldToSearch": {
          "type": "text",
          "norms": false
        }
      }
    }
    

    但我认为更准确的查询会是更好的选择。

    编辑:

    我的观点只是使用包含相对独特标记的更具体的查询。例如,与其查询几乎包含在索引中每个文档中的短语 Jurassic Park,不如查询仅包含在一个文档中的 World Jurassic Park

    但是,有一种方法可以实现您的示例所需的结果。看this问题。您需要更改映射以在某些字段上启用令牌计数器:

    PUT your_index/_mapping/your_type
    {
      "properties": {
        "FieldToSearch": { 
          "type": "text",
          "fields": {
            "length": { 
              "type": "token_count",
              "analyzer": "standard"
            }
          }
        }
      }
    }
    

    然后使用function_score 根据该字段包含的令牌计数来提高相关性:

    GET your_index/your_type/_search
    {
      "query": {
        "function_score": {
          "query": {"match_phrase": {
            "title": "Jurassic Park"
          }},
          "field_value_factor": {
            "field": "FieldToSearch.length",
            "modifier": "reciprocal"
          }
        }
      }
    }
    

    这样,字段包含少量token的文档将获得更高的分数。

    【讨论】:

    • 谢谢,这就解释了为什么我会得到这些奇怪的结果。我宁愿避免修改索引,因为我是弹性搜索的新手,不知道所有的后果。您能否举例说明在这种情况下如何进行更准确的查询?例如,假设我正在为所有标题中包含“侏罗纪公园”的电影搜索电影收藏。在列出“失落的世界:侏罗纪公园”和“侏罗纪公园 III”之前,我将如何编写一个列出“侏罗纪公园”的查询?
    • @PierceMason 我刚刚编辑了我的答案。请查看最新版本。
    • 谢谢,我希望有一种方法可以简化查询,但听起来添加令牌计数可能会起作用。在这种情况下,短语来自用户,因此我无法将短语的内容更改为更相关
    • @PierceMason 好的。作为一个小补充,Elasticsearch 指南中有一个article,在我看来,它准确地描述了你的情况。
    • 谢谢,那篇文章有助于解释事情。我们正在设置 elasticsearch 并且还没有所有数据,所以看起来这个问题最终可能会得到缓解(根据那篇文章)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-15
    • 2020-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多