elasticsearch嵌套范围查询

时间:2018-05-25 08:27:22

标签: elasticsearch

假设我想要一个文档的结构:

{
  "hours": {
    "open": [
      {
        "start": 10,
        "end": 19
      },
      {
        "start": 21,
        "end": 29
      }
      ...
    ],
    "closed": [
      {
        "start": 100,
        "end": 199
      },
      {
        "start": 201,
        "end": 299
      }
      ...
    ]
  }
}

其索引具有此映射:

{
  "mappings": {
    "_doc": {
      "properties": {
        "hours": {
          "properties": {
            "open": {
              "type": "nested",
              "properties": {
                "start": { "type": "integer" },
                "end": { "type": "integer" }
              }
            },
            "closed": {
              "type": "nested",
              "properties": {
                "start": { "type": "integer" },
                "end": { "type": "integer" }
              }
            }
          }
        }
      }
    }
  }
}

在Elasticsearch Query DSL中,我如何找到 20 位于开放段内而不是封闭段内的所有文档。我试过的查询不正确。

查询失败

{
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "must": [
              {
                "nested": {
                  "path": "hours.open",
                  "query": {
                    "range": {
                      "hours.open.start": { "lte": 20 }
                    }
                  }
                }
              },
              {
                "nested": {
                  "path": "hours.open",
                  "query": {
                    "range": {
                      "hours.open.end": { "gte": 20 }
                    }
                  }
                }
              }
            ]
          }
        },
        {
          "bool": {
            "must_not": [
              {
                "bool": {
                  "must": [
                    {
                      "nested": {
                        "path": "hours.closed",
                        "query": {
                          "range": {
                            "hours.closed.start": { "lte": 20 }
                          }
                        }
                      }
                    },
                    {
                      "nested": {
                        "path": "hours.closed",
                        "query": {
                          "range": {
                            "hours.closed.end": { "gte": 20 }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  }
}

我的查询有什么问题?它返回的这份文件不是我想要的。 20不在开放段内。

2 个答案:

答案 0 :(得分:0)

好像你需要交换lte和gte:

"hours.open.start": { "gte": 20 }
"hours.open.end": { "lte": 20 }

并且关闭时间相同:

"hours.closed.start": { "gte": 20 }
"hours.closed.end": { "lte": 20 }

修改: must和must_not需要成为同一个bool查询的一部分:

{
    "query": {
        "bool": {
            "must": [{
                    "nested": {
                        "path": "hours.open",
                        "query": {
                            "range": {
                                "hours.open.start": {
                                    "gte": 20
                                }
                            }
                        }
                    }
                },
                {
                    "nested": {
                        "path": "hours.open",
                        "query": {
                            "range": {
                                "hours.open.end": {
                                    "lte": 20
                                }
                            }
                        }
                    }
                }
            ],
            "must_not": [{
                "bool": {
                    "must": [{
                            "nested": {
                                "path": "hours.closed",
                                "query": {
                                    "range": {
                                        "hours.closed.start": {
                                            "gte": 20
                                        }
                                    }
                                }
                            }
                        },
                        {
                            "nested": {
                                "path": "hours.closed",
                                "query": {
                                    "range": {
                                        "hours.closed.end": {
                                            "lte": 20
                                        }
                                    }
                                }
                            }
                        }
                    ]
                }
            }]
        }
    }
}

答案 1 :(得分:0)

我终于开始工作了。以下是正确的查询:

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "hours.open",
            "query": {
              "bool": {
                "must": [
                  { "range": { "hours.open.start": { "lte": 20 } } },
                  { "range": { "hours.open.end": { "gte": 20 } } }
                ]
              }
            }
          }
        }
      ],
      "must_not": [
        {
          "nested": {
            "path": "hours.closed",
            "query": {
              "bool": {
                "must": [
                  { "range": { "hours.closed.start": { "lte": 20 } } },
                  { "range": { "hours.closed.end": { "gte": 20 } } }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

话虽如此,看起来我原来的尝试是错误的,因为有两个不同的hours.open嵌套路径查询和两个不同的hours.closed嵌套路径查询。解析器只能将其中一个用于单个路径。