ES单字符串多字段查询: disjunction max query

当需要对同一个字符串在多个字段中进行查询时,用bool查询在算分时会对多个查询结果的算分进行平均,而实际上有可能我们需要的是最匹配的那个字段对应的那条记录,这个时候就可以用到disjunciton max query 了。

一,插入演示数据

PUT dis_max_index/_bulk
{"index":{"_id":1}}
{"title":"apple key", "name":"i like iphone"}
{"index":{"_id":2}}
{"title":"2 key", "name":"i like apple iphone"}

二,bool查询

需求是查询title和name中apple iphone匹配度最高的文档,明显第二个文档匹配度更高,但查询的结果是两个文档评分相同,原因就在于bool查询会把多个字段的查询结果进行综合算分。

第一个文档的title字段中能匹配到apple,name字段中能匹配到iphone,匹配词数为2。

第二个文档title中未匹配到,name中匹配到apple iphone,匹配词数也是2。

最后进行综合评分,两个文档的评分一致,实际上需要是要匹配到第二个文档。

GET dis_max_index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": "apple iphone"
          }
        },
        {
          "match": {
            "title":"apple iphone"
          }
          
        }
      ]
    }
  }
}

三,disjunction max query

dis max 会将单个字段查询匹配最高的那个文档首先查询出来。

GET dis_max_index/_search
{
  "query": {
    "dis_max": {
      "boost": 1.2,
      "queries": [
        {
          "match": {
            "name": "apple iphone"
          }
        },
        {
         "match": {
            "title": "apple iphone"
          }
        }
      ]
    }
  }
}

四,disjunction max query 之tie breaker

还有一种情况就是虽然使用了dis max,但两个文档的评分还是一样,这个时候就可以将另外一个字段的加入算分过程,使用tie_breaker设置非最高匹配字段的权重。

测试数据:

PUT dis_max_index/_bulk
{"index":{"_id":3}}
{"title":"good key", "name":"i like iphone"}
{"index":{"_id":4}}
{"title":"good key", "name":"i like china iphone"}

在下面的查询中,本来good key能匹配到两个文档,而且评分是一样的,但由于我们添加了tie_breaker参数,会将另外的非最高匹配字段加入算分,因为第二个文档name匹配到了china,所以第二个文档综合算分比较高。

GET dis_max_index/_search
{
  "query": {
    "dis_max": {
      "tie_breaker": 0.1,
      "boost": 1.2,
      "queries": [
         {"match":{"title":"good key"}},
         {"match":{"name":"china"}}
      ]
    }
  }
}

你可能感兴趣的:(java)