elasticsearch 父子文档使用must not 正确姿势

得意时要看淡,失意时要看开。不论得意失意,切莫大意;不论成功失败,切莫止步。志得意满时,需要的是淡然,给自己留一条退路;失意落魄时,需要的是泰然,给自己觅一条出路elasticsearch 父子文档使用must not 正确姿势,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

需求描述:

1、基于elasticsearch 父子文档进行子条件查询父文档
2、需要查询出子文档不存在的父文档

已知文档结构:

1、父文档clue_list 关联很多的子文档,我们用roam子文档做测试!
在这里插入图片描述
2、roam子文档的结构

{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 5.4327264,
    "hits" : [
      {
        "_index" : "clue_list",
        "_type" : "_doc",
        "_id" : "roam_668414740279590913",
        "_score" : 5.4327264,
        "_routing" : "668164507591245825",
        "_source" : {
          "companyId" : 1,
          "companyRoamCount" : 0,
          "centreRoamCount" : 0,
          "depRoamCount" : 2,
          "publicRoamCount" : 0,
          "joinFiled" : {
            "parent" : "668164507591245825",
            "name" : "roam"
          }
        }
      }
    ]
  }
}

小试牛刀

需求是查询出roam子文档不存在的数据,由于我们es的所有数据companyId == 1 我们可以用must not来排除 companyId == 1的数据

1、错误的查询方式,直接must not匹配

GET clue_list/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "joinFiled": {
              "value": "clue_list"
            }
          }
        },{
          "has_child": {
            "type": "roam",
            "query": {
              "bool": {
                "must_not": [
                  {
                    "term": {
                      "companyId": {
                        "value": 1
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

结果:

{
  "took" : 80,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

结论:直接匹配没有查询出目标数据,由于must not排除了companyId == 1的数据,但是由于我们数据库并没有其他数据,此时查询子文档返回数据为空,子文档为空匹配父文档造成返回数据为空。

2、正确的姿势,先查询出companyId == 1的数据,然后取反将must not放在外层
es执行语句:

GET clue_list/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "joinFiled": {
              "value": "clue_list"
            }
          }
        },{          
          "bool": {
            "must_not": [
              {
                "has_child": {
                  "type": "roam",
                  "query": {
                    "term": {
                      "companyId": {
                        "value": 1
                      }
                    }
                  }
                }
              }
            ]
          }
          
        }
      ]
    }
  }
}

响应数据:
在这里插入图片描述

验证第一条数据是否不存在roam子文档:
在这里插入图片描述

结论:正确查询出不存在roam子文档的数据

寄语:
es父子文档查询通过子文档过滤父文档且需要用到must not的时候,如果有子文档有为空的情况,则需要先查询不满足条件的再在父层级进行排除,如果子文档一定不会为空才能够直接进行排除操作;
当然,懒人适用的方式就是直接用第二种方案,都在上层进行排除不满足条件的数据。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/154711.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!