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

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

作者: b335eb9201c3 | 来源:发表于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