屏蔽 pickup/dropoff 的某些日期范围

Block certain date ranges for pickup/dropoff

我有东西要出租。用户指定 start_dateend_date。每个项目都有多个 blocked_periods 也有开始和结束日期。

目标:

查询所有可用项目。让我们说: 12 月 11 日、13 月 11 日、14 月 11 日、15 月 11 日

13 号和 14 号被屏蔽

商品应在 12 日或 15 日或 12 日至 15 日有售,但开始和结束日期不能在 13 日和 14 日

当前索引:

{
  "development_items" : {
    "aliases" : { },
    "mappings" : {
      "item" : {
        "properties" : {
          "blocked_periods" : {
            "type" : "nested",
            "properties" : {
              "end_date" : {
                "type" : "date",
                "format" : "yyyy-MM-dd"
              },
              "start_date" : {
                "type" : "date",
                "format" : "yyyy-MM-dd"
              }
            }
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1503327829680",
        "number_of_shards" : "5",
        "number_of_replicas" : "1",
        "uuid" : "9b9BhF-ITta2dlCKRLrnfA",
        "version" : {
          "created" : "2040499"
        }
      }
    },
    "warmers" : { }
  }
}

当前查询:

  {
    bool: {
      must_not: {
        nested: {
          path: 'blocked_periods',
          query: {
            bool: {
              should: [
                {
                  bool: {
                    must: [
                      {
                        range: {
                           'blocked_periods.start_date': {
                             lte: start_date
                           }
                        }
                      },
                      {
                        range: {
                           'blocked_periods.end_date': {
                             gte: end_date
                           }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          }
        }
      }
    }
  }

您想要给定开始时间不在阻塞期间且给定结束时间不在阻塞期间的文档。另一种说法是 您不想要给定开始处于阻塞期或给定结束处于阻塞期 (!A AND !B === !(A OR B)) 的文档。

如果我们坚持使用您的映射并以嵌套方式执行此操作,方法如下:

{
  "query": {
    "bool": {
      "must_not": [
        {
          "nested": {
            "path": "blocked_periods",
            "query": {
              "bool": {
                "should": [
                  {
                    "bool": {
                      "must": [
                        {
                          "range": {
                            "blocked_periods.start_date": {
                              "lte": "START" 
                            }
                          }
                        },
                        {
                          "range": {
                            "blocked_periods.end_date": {
                              "gte": "START"
                            }
                          }
                        }
                      ]
                    }
                  },
                  {
                    "bool": {
                      "must": [
                        {
                          "range": {
                            "blocked_periods.start_date": {
                              "lte": "END"
                            }
                          }
                        },
                        {
                          "range": {
                            "blocked_periods.end_date": {
                              "gte": "END"
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

但是,如果您可以处理将字段名称从 start_date/end_date 更改为 gte/lte,我认为您会发现 date_range 方法更可取。

PUT my_index
{
  "mappings": {
    "item": {
      "properties": {
        "blocked_periods": {
          "type": "date_range",
          "format": "yyyy-MM-dd"
        }
      }
    }
  }
}

POST my_index/item/1
{
  "blocked_periods": [
    {
      "gte": "2020-1-10",
      "lte": "2020-1-15"
    },
    {
      "gte": "2020-1-17",
      "lte": "2020-1-25"
    }
  ]
}

GET my_index/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "term": {
            "blocked_periods": "START"
          }
        },
        {
          "term": {
            "blocked_periods": "END"
          }
        }
      ]
    }
  }
}