我有预订的公寓。我的索引保留为嵌套字段,其中包含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" : { }
}
}
答案 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中查看我的解决方案
我创建并举例说明,填充样本索引并使用此查询搜索所需的公寓
评论答案:
前缀:由于执行了嵌套过滤器,因此将查询设置路径,根本不需要前缀(至少在我的测试版本中)。是的,您可以在文档级别或另一个嵌套字段中添加字段名称start_date
公寓匹配:是的,它与91个样本公寓匹配,但由于我使用默认search
参数进行了size
,因此只返回10个(我没有指定其值,它的默认值)。如果您需要获取所有这些内容,请使用scroll search
(笔记本已被修改以澄清这一点)
答案 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-10
和2017-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"
}
}
}
]
}
}
}
}
]
}
}
]
}
}