1

elasticsearch 嵌套文档查询问题

 2 years ago
source link: https://www.v2ex.com/t/817085
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

V2EX  ›  Elasticsearch

elasticsearch 嵌套文档查询问题

  CRUD · 13 小时 13 分钟前 · 401 次点击

求问一个 es 嵌套文档查询,仅当查询范围内所有嵌套文档都满足条件时才返回,而不是只要有一个嵌套文档满足条件就返回。

我的场景是按天建立嵌套文档,筛选时给定日期范围,需要筛选出该日期范围内每天都满足筛选条件的文档,目前我自己写的搜索语法只要日期范围内有一天满足就会返回..

我的文档结构如下:

{
    "mappings": {
        "properties": {
            "adResource": {
                "type": "nested",
                "properties": {
                    "day": {
                        "type": "date",
                        "format": "yyyy-MM-dd || epoch_millis"
                    },
                    "total": {
                        "type": "integer"
                    },
                    "subResource": {
                        "type": "nested",
                        "properties": {
                            "hours": {
                                "type": "integer"
                            },
                            "total": {
                                "type": "integer"
                            }
                        }
                    }
                }
            }
        }
    }
}

数据示例:

{
    "adResource": [
        {
            "total": 1800,
            "subResource": [
                {
                    "hours": 0,
                    "total": 0
                },
                {
                    "hours": 3600,
                    "total": 0
                },
                {
                    "hours": 7200,
                    "total": 0
                },
                {
                    "hours": ...,
                    "total": ...
                },
                {
                    "hours": 82800,
                    "total": 0
                }
            "day": "2021-11-20"
        },
        {
           "total": 5200,
           "subResource":[......]
           "day": "2021-11-21"
        }
    ]
}

需求:检索的时候给定一个日期区间和小时区间,要求检索出日期区间和小时区间内资源全部满足的文档,例如给定检索条件:

{
    "dayStart": "2021-11-20",
    "dayEnd": "2021-11-21",
    "total": 540,
    "subResource": [
        {
            "hour": 0,
            "total": 180
        },
        {
            "hour": 3600, // hour 3600 表示 1:00:00 到 1:59:59 的区间
            "total": 360
        }
    ]
}

表示 20 、21 这两天的 total>540 ,且这两天内的 hour 0 > 180 && hour 3600 > 360

目前的搜索语法如下,该搜索会返回 20 、21 这两天只有一天满足条件的文档,而我需要的是两天都满足的文档:

{
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "adResource",
            "query": {
              "bool": {
                "must": [
                  {
                    "range": {
                      "adResource.day": {
                        "gte": "2021-11-20",
                        "lte": "2021-11-21"
                      }
                    }
                  },
                  {
                    "nested": {
                      "path": "adResource.subResource",
                      "query": {
                        "bool": {
                          "must": [
                            {
                              "bool": {
                                "must": [
                                  {
                                    "term": {
                                      "adResource.subResource.hours": {
                                        "value": "0"
                                      }
                                    }
                                  },
                                  {
                                    "range": {
                                      "adResource.subResource.total": {
                                        "gte": 180
                                      }
                                    }
                                  }
                                ]
                              }
                            },
                            {
                              "bool": {
                                "must": [
                                  {
                                    "term": {
                                      "adResource.subResource.hours": {
                                        "value": "3600"
                                      }
                                    }
                                  },
                                  {
                                    "range": {
                                      "adResource.subResource.total": {
                                        "gte": 360
                                      }
                                    }
                                  }
                                ]
                              }
                            }
                          ]
                        }
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK