禁止某些日期范围上门/下车

时间:2018-11-04 13:25:46

标签: elasticsearch chewy-gem

我有要出租的物品。用户指定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
                           }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          }
        }
      }
    }
  }

1 个答案:

答案 0 :(得分:1)

您要记录给定的开始时间不在阻止时间段内并且给定的结束时间不在阻止时间段内。换句话说,这是 您不希望文档中给定的起始时间处于阻止时段或给定的结束时间处于阻止时段(!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"
          }
        }
      ]
    }
  }
}