query_string和minimum_should_match歧义问题

1. query_string针对索引不存在字段的处理逻辑变化:

如下DLS:语义为查询此字段(索引内不存在)不包含柔的文档。

{
  "size": 1,
  "track_total_hits": true,
  "_source": "text_content",
  "profile": "true",
  "query": {
    "query_string": {
      "analyzer": "ik_max_word",
      "query": """(NOT("柔"))""",
      "fields": [
        "text_title"
      ]
    }
  }
}
  • 因为此字段不存在,所以去除NOT改为此字段包含柔的文档返回结果为0,这里不存在歧义,6.7/7.10版本es返回结果一致。profile API验证均如下:
 "type" : "MatchNoDocsQuery",
 "description" : """MatchNoDocsQuery("empty BooleanQuery")""",
  • 添加NOT后,因为字段不存在,查询不存在字段不包含柔的文档是返回0?还是理解为对不带NOT的语句取非,返回全部?这里6和7版本表现不同:
    6.7.0版本:
    与不带NOT的结果一致返回0条文档,且profile显示语法也一致
    7.10.2版本:
    做了改变,返回全部文档,profile显示语法添加了一个MatchAllDocsQuery(*:*)如下图所示。含义大概是NOT语义为不带NOT取非,不带NOT返回0条则NOT应该返回全部?
    7.10.2版本NOT语义

2. minimum_should_match歧义

minimum_should_match正常理解应该应用于 bool 查询的 should 子句上,来控制最小匹配 should 子句的数量。
默认值(翻译自官网): 如果 bool 查询包含至少一个 should 子句,且无 must 和 fliter 子句,则为1;否则为0。

再说上段中7.10版本查询不存在字段的NOT语句返回为全部文档,默认 minimum_should_match 为0,我们把他改成1:

{
  "size": 1,
  "track_total_hits": true,
  "_source": "text_content",
  "profile": "true",
  "query": {
    "query_string": {
      "analyzer": "ik_max_word",
      "query": """(NOT("柔"))""",
      "fields": [
        "text_title"
      ],
      "minimum_should_match": "1"
    }
  }
}

返回结果为0条,而不是之前的全部文档。profile分析如下:
mini设置为1
奇怪的事情发生了,存在MatchAllDocsQuery子句至少满足1子句理论上应该还是返回全部文档,但是却返回了0条?

3. 继续分析minimum_should_match

需要针对正常的 DSL bool 查询和 query_string 的NOT AND OR
等bool查询分别分析minimum_should_match的作用和差异(7.10 版本&针对存在的字段查询)。

3.1. AND

query_string:

"query": """(("柔")AND("脊"))"""

dsl bool:

"query": {
  "bool": {
    "must": [
      {
        "match": {
          "text_content": "柔"
        }
      },
      {
        "match": {
          "text_content": "脊"
        }
      }
    ]
  }
}

经profile分析两个语句语一致为+text_content:柔 +text_content:脊,返回文档数量也一致。由minimum_should_match特性可知现在它的值为0,修改为1后:dsl bool 和 query_string 语法解析变为(+text_content:柔 +text_content:脊)~1且返回数据条数变为0。

3.2. NOT

query_string:

"query": """(NOT("柔"))"""

dsl bool:

"query": {
  "bool": {
    "must_not": [
      {
        "match": {
          "text_content": "柔"
        }
      }
    ]
  }
}

经profile分析两个语句语一致如下图,返回文档数量也一致。
NOT语义
minimum_should_match特性可知现在它的值为0,修改为1后:
dsl bool语义和返回结果没有发生变化;
query_string返回结果为0,且语义变为下图:
query_string NOT mini:1
在这里 query_string 和 dsl bool 的语义产生差异。

3.3 OR

query_string:

"query": """(("柔")OR("脊"))"""

dsl bool:

"query": {
  "bool": {
    "should": [
      {
        "match": {
          "text_content": "柔"
        }
      },
      {
        "match": {
          "text_content": "脊"
        }
      }
    ]
  }
}

minimum_should_match特性可知现在它的值应该为1,经测试:
当它的值设置为0时:语义为text_content:柔 text_content:脊
当它的值设置为1时:语义为(text_content:柔 text_content:脊)~1
且不设置它的值时为0语义,即默认值为0。query_string 和 dsl bool 在此场景下语义和返回结果一致。包括设置为2时,语义转变为(text_content:柔 text_content:脊)~2等同于must语义。
**综上:**在ANDNOT的情境下minimum_should_match均出现异常,只有在should下表现正常。

//TODO
AND OR NOT 组合使用以及minimum_should_match异常原因分析…

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>