获取可用的公寓查询

时间:2017-02-16 22:40:05

标签: elasticsearch chewy-gem

概述

我有预订的公寓。我的索引保留为嵌套字段,其中包含start_date和end_date的日期字段。

我正在使用耐嚼的红宝石宝石 - 但我认为这在此时无关紧要。只需要让我的查询正确。

目标

我想取得所有在指定日期没有预订但根本没有预订的公寓。

当前查询

不幸的是归还所有公寓:

:query => {
  :bool => {
    :must_not => [
      {
        :range => {:"reservations.start_date" => {:gte => "2017-02-10"}}
      }, 
      {
        :range => {:"reservations.end_date" => {:lte => "2017-02-12"}}
      }
    ]
  }
}

索引设置

{
  "apartments" : {
    "aliases" : { },
    "mappings" : {
      "apartment" : {
        "properties" : {
          "city" : {
            "type" : "string"
          },
          "coordinates" : {
            "type" : "geo_point"
          },
          "email" : {
            "type" : "string"
          },
          "reservations" : {
            "type" : "nested",
            "properties" : {
              "end_date" : {
                "type" : "date",
                "format" : "yyyy-MM-dd"
              },
              "start_date" : {
                "type" : "date",
                "format" : "yyyy-MM-dd"
              }
            }
          },
          "street" : {
            "type" : "string"
          },
          "zip" : {
            "type" : "string"
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1487289727161",
        "number_of_shards" : "5",
        "number_of_replicas" : "1",
        "uuid" : "-rM79OUvQ3qkkLJmQCsoCg",
        "version" : {
          "created" : "2040499"
        }
      }
    },
    "warmers" : { }
  }
}

3 个答案:

答案 0 :(得分:1)

我们必须列出所需时段内可用的免费公寓和公寓(start_date,end_date变量)

所以它应该是一个或查询:free_aparments或available_aparments

免费公寓(那些在预订字段中没有任何价值的公寓)应该很容易查询丢失的过滤器,但这是一个嵌套的字段,我们必须处理。
如果我们使用缺少的过滤器执行查询,则将返回所有文档。这很奇怪,但它发生了。这里有解释的解决方案:https://gist.github.com/Erni/7484095以下是问题:https://github.com/elastic/elasticsearch/issues/3495要点snnipet适用于所有弹性搜索版本。

该查询的另一部分是可用的公寓。
我已经解决了这部分执行非查询。给我那些没有预订的公寓,想一个与那些有预订的公寓相匹配的范围列表,然后使用must_not过滤器否定结果

elasticsearch_query = {
    "query": {
        "filtered": {
            "filter": {
                "bool": {
                    "should": [
                        {
                            "nested": {
                                "filter": {
                                    "bool": {
                                        "must_not" : [
                                            {
                                                "range": {
                                                    "start_date": {
                                                        "gte" : start_date, 
                                                        "lt" :end_date
                                                    }
                                                }
                                            },
                                            {
                                                "range": {
                                                    "end_date": {
                                                        "gte" : end_date, 
                                                        #"lte" :end_date
                                                    }
                                                }
                                            }
                                        ]
                                    }
                                }, 
                                "path": "reservations"
                            }
                        },
                        {
                            #{ "missing" : { "field" : "reservations"} }
                            "not": {
                                "nested": {
                                    "path": "reservations",
                                    "filter": {
                                        "match_all": {}
                                    }
                                }
                            }
                        }
                    ],
                }
            }
        },
    }, 
    "sort" : {"id":"desc"}
}

您可以在this notebook中查看我的解决方案 我创建并举例说明,填充样本索引并使用此查询搜索所需的公寓

评论答案:

  1. 前缀:由于执行了嵌套过滤器,因此将查询设置路径,根本不需要前缀(至少在我的测试版本中)。是的,您可以在文档级别或另一个嵌套字段中添加字段名称start_date

  2. 公寓匹配:是的,它与91个样本公寓匹配,但由于我使用默认search参数进行了size,因此只返回10个(我没有指定其值,它的默认值)。如果您需要获取所有这些内容,请使用scroll search


  3. (笔记本已被修改以澄清这一点)

答案 1 :(得分:0)

首先,我认为你必须使用nested query

我对chewy-gem不熟悉,但查询看起来像:

:query => {
  :nested: => {
    :path: => "reservations",
    :query => {
      :bool => {
        :must_not => [ 
          {
            :range => {:"reservations.start_date" => {:gte => "2017-02-10"}}
          }, 
          {
            :range => {:"reservations.end_date" => {:lte => "2017-02-12"}}
          }
        ]
      }
    }
  }
}

但它可能也不起作用,好像2018年有预订,fisrt bool查询将为真(因为开始日期将是> 2017-02-10),因此如果公寓将不会返回,如果我没错。

我会做类似的事情:

:query => {
  :nested: => {
    :path: => "reservations",
    :query => {
      :bool => {
        :must_not => [ 
          {
            :range => {:"reservations.start_date" => {:gte => "2017-02-10", :lte => "2017-02-12"}}
          }, 
          {
            :range => {:"reservations.end_date" => {:gte => "2017-02-10", :lte => "2017-02-12"}}
          }
        ]
      }
    }
  }
}

表示在您想要的范围之间没有开始日期,在您想要的范围之间没有结束日期。

答案 2 :(得分:0)

这是我想出的查询,应该考虑所有条件,即:

  • 要么没有预订(第一个顶级bool/should
  • 或至少有一个预订,预订开始和结束日期与请求的日期不重叠。

在此,我们要求2017-02-102017-02-12

之间的免费公寓
{
  "bool": {
    "minimum_should_match": 1,
    "should": [
      {
        "nested": {
          "path": "reservations",
          "query": {
            "bool": {
              "must_not": {
                "exists": {
                  "field": "reservations.start_date"
                }
              }
            }
          }
        }
      },
      {
        "bool": {
          "must": [
            {
              "nested": {
                "path": "reservations",
                "query": {
                  "bool": {
                    "minimum_should_match": 1,
                    "should": [
                      {
                        "range": {
                          "reservations.start_date": {
                            "gt": "2017-02-10"
                          }
                        }
                      },
                      {
                        "range": {
                          "reservations.end_date": {
                            "lt": "2017-02-10"
                          }
                        }
                      }
                    ]
                  }
                }
              }
            },
            {
              "nested": {
                "path": "reservations",
                "query": {
                  "bool": {
                    "minimum_should_match": 1,
                    "should": [
                      {
                        "range": {
                          "reservations.start_date": {
                            "gt": "2017-02-12"
                          }
                        }
                      },
                      {
                        "range": {
                          "reservations.end_date": {
                            "lt": "2017-02-12"
                          }
                        }
                      }
                    ]
                  }
                }
              }
            }
          ]
        }
      }
    ]
  }
}