Elasticsearch如何替换“术语”查询?

时间:2019-02-04 23:54:34

标签: elasticsearch search

在版本6之前使用Elasticsearch,以下查询基于与查询的相似性返回匹配。现在,在ES 6+中,这将根据它们是否匹配查询的任何部分(均具有相同分数)返回匹配。此更改将打破其余更复杂的查询(未显示)。

对于以下查询,如何获得与旧版ES 5匹配的命中分数

{
  "query": {
    "bool": {
      "should": [
        {
          "terms": {
            "some_field_name": [
              "iPad Pro",
              "iPhone 8"
            ]
          }
        }
      ]
    }
  }
}

在ES 5中,此结果返回的命中值与所有字词匹配的得分较高,而与之匹配的得分较低。在ES 6+中,此匹配仅返回得分= 1的匹配,因此,它们的排名不考虑匹配项的数量。

例如,具有两个字词的匹配在ES 5中排名较高:

"_score": 0.87546873, when 2 of 4 terms match
"_score": 0.60353506, when 2 of 5 terms match
"_score": 0.13353139, when 1 of 4 terms match

这很像我们所需的“余弦”相似度(理解为这并非精确地创建分数)。

对于上述查询,哪种查询将返回与ES 5相同的分数。换句话说,什么是ES 6等效查询?

1 个答案:

答案 0 :(得分:0)

注意:由于评论中的讨论越来越长且笨拙,因此只能将其作为建议草案发布。

更新:刚刚检查了我建议的两种方法,两者似乎都给出了相似的评分。请尝试这些方法,看看您获得的分数是否与您相关。

我知道它不适用于术语,但是我建议将其替换为也具有boost参数的多个“ term”过滤器,或者将其替换为“ term_set”查询,并将required_matches参数设置为“ 1”,因为我们想要“或”行为。

1)使用terms_set查询:

{
  "query": {
    "bool": {
      "should": [
        {
          "terms_set": {
            "some_field_name": {
             "terms" : ["iPad Pro", "iPhone 8"],
             "minimum_should_match_script": {
                "source": "1"
              } 

            }
          }
        }
      ]
    }
  }
}

2)使用多个术语过滤器代替单个术语过滤器:

{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "some_field_name": "iPad Pro"
          }
        },
        {
          "term": {
            "some_field_name": "iPhone 8"
          }
        }
      ]
    }
  }
}

如果您使用术语提升,则应在每个术语块中应用相同的提升。