首页 > 解决方案 > Elasticsearch嵌套字段:嵌套查询内必须与嵌套查询内必须

问题描述

我正在对嵌套字段执行范围查询task__distributions

第一个在必须查询中放置两个嵌套查询。第二个在一个嵌套查询中执行必须查询。

我认为这两个会返回相同的结果,但我只得到第二个查询的正确结果(不返回结果)。

这两个查询有什么区别吗?

{
    "query": {
        "bool": {
            "must": [
                {
                    "nested": {
                        "path": "task__distributions",
                        "query": {
                            "range": {
                                "task__distributions.publishDate": {
                                    "gte": "2021-09-30T18:00:00.000Z"
                                }
                            }
                        }
                    }
                },
                {
                    "nested": {
                        "path": "task__distributions",
                        "query": {
                            "range": {
                                "task__distributions.publishDate": {
                                    "lte": "2021-10-31T17:59:59.999Z"
                                }
                            }
                        }
                    }
                }
            ]
        }
    }
}
{
    "query": {
        "nested": {
            "path": "task__distributions",
            "query": {
                "bool": {
                    "must": [
                        {
                            "range": {
                                "task__distributions.publishDate": {
                                    "gte": "2021-09-30T18:00:00.000Z"
                                }
                            }
                        },
                        {
                            "range": {
                                "task__distributions.publishDate": {
                                    "lte": "2021-10-31T17:59:59.999Z"
                                }
                            }
                        }
                    ]
                }
            }
        }
    }
}

标签: elasticsearch

解决方案


是的,这两个查询之间存在显着差异。重要的是嵌套查询的级别。在第一个查询中,两个嵌套查询相互独立,可以匹配不同的嵌套对象,在第二个查询中,两个必须查询应用两个相同的嵌套对象。

尝试用自然语言描述查询:

  1. 匹配包含发布日期为gte 2021-09-30 的任务分布和包含发布日期为lte 2021-10-31 的任务分布的所有文档。

  2. 匹配具有发布日期gte 2021-09-30 和lte 2021-10-31的任务分布的所有文档

所以让我们假设我们有这个文件:

    "_source" : {
      "task__distribution" : [
        {
          "task" : "123",
          "publish_date" : "2021-09-01T18:00:00.000Z"
        },
        {
          "task" : "234",
          "publish_date" : "2021-11-01T18:00:00.000Z"
        }
      ]
    }

第一个查询将匹配,因为第一个嵌套字段(任务 123)具有发布日期gte 2021-09-30 和第二个嵌套字段(任务 234)具有发布日期lte 2021-10-31 的任务分布。

但是,第二个查询与该文档不匹配,因为这两个发布日期都不在两个给定日期之间。这是您想要的行为。

您可以查看嵌套查询文档以获取更多详细信息。

这种行为的原因可以从文档中解释:

嵌套查询搜索嵌套字段对象,就好像它们被索引为单独的文档一样。如果对象与搜索匹配,则嵌套查询将返回根父文档。


推荐阅读