0

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

1 回答 1

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_dateto 更改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"
          }
        }
      ]
    }
  }
}
于 2018-11-05T10:52:08.837 回答