美文网首页
es的nested在使用must_not嵌套exists不生效的

es的nested在使用must_not嵌套exists不生效的

作者: 小民自愚 | 来源:发表于2023-10-26 14:37 被阅读0次

最近在使用es的过程中,要查询nested嵌套查询不存在的字段,查询结果不尽人意,做一下分析
1.索引数据

{
    "catSource":"JC",
    "planMonth":null,
    "sendBidTime":null,
    "planStatus":null,
    "planName":null,
    "secondCatName":"children3-1",
    "source":null,
    "projectSysNo":null,
    "relation":{
        "parent":"YJH20231018004040",
        "name":"planMonthlyItem"
    },
    "tenderType":"PUBLIC",
    "updaterId":10020051,
    "areaName":null,
    "planItemCode":"yjh-1714582956141731861",
    "bidDocProjectReviewStartTime":null,
    "planTenderStartTime":1697558400000,
    "sourceType":"NEW",
    "coreAttrName":null,
    "plannedCnt":null,
    "updaterName":"这是一个很长很长很长很长很长的名字",
    "changeStatus":null,
    "projectName":null,
    "estimatedAmount":1,
    "tenderRelList":[

    ],
    "tenderDays":null
}

2.查询语句

GET idx_ppls_plan_monthly_info_qa/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "terms": {
            "planItemCode": ["yjh-1714582956141731861"]
          }
        },
        {
          "nested": {
            "path": "tenderRelList",
            "query": {
              "bool": {
                "must_not": {
                  "exists": {
                    "field": "tenderRelList.id"
                  }
                }
              }
            }
          }
        }
      ]
    }
}
}

查询结果如下,未查到

image.png
3.将查询语句改为如下方式
GET idx_ppls_plan_monthly_info_qa/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "terms": {
            "planItemCode": ["yjh-1714582956141731861"]
          }
        },
        {
          "bool": {
            "must_not": [
              {
                "nested": {
                  "path": "tenderRelList",
                  "query": {
                    "exists": {
                      "field": "tenderRelList.id"
                    }
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

查询结果如下,正常返回数据

image.png
4.查询分析
单从查询语句分析,这2种查询方式看起来是一样的,都是要查询code为XXX的数据,并且tenderRelList为空的数据,但是返回结果截然相反,很奇怪。
网上查找了一下,没有找到原因,让chatgpt分析了一下,也是没分析出来,chatgpt认为2种查询方式返回的结果应该一样
image.png
然后,自己研究了一下,分析如下:
1.先看es的内部执行计划
image.png
image.png
从执行计划可以看出,第一种查询方式,是在查询了code的同时,还去查询了子数据,然后取交集,因为第一种写法,term查询之后,并没有and的关系,是直接去nested执行子查询,然后将2个查询结果取了交集,所以返回结果为空。
第2种查询方式,是在查询了code返回的数据后,在该数据的基础上过滤nested不存在的数据,所以这种查询是返回了结果的。
第一种查询的子查询,是直接查询了nested的子索引文档,因为他是先在子文档查询id不存在的数据,因为不存在这样的数据,所以没法反推出主文档的数据,因此返回结果为空,跟主查询取交集,就没数据了.
验证如下:
查询子文档存在,其中某个字段为空的数据,发现可以查到数据
image.png
查询子文档不存在,结果为空,跟一开始的查询结果是一致的
image.png
2.再看下直接查子文档不存在的执行计划
image.png
image.png
显然,第二种查询是查主文档存在,并且子文档进行过滤

相关文章

网友评论

      本文标题:es的nested在使用must_not嵌套exists不生效的

      本文链接:https://www.haomeiwen.com/subject/jqvyidtx.html