我计划在弹性研究中储存数百万可供选择的气垫式公寓。
其中availabilty
是包含nested
个对象的数组(availability
类型为nested
)。
每个对象都有日期范围,可以使用该公寓。
apartments = [
{
"_id": "kjty873yhekrg789e7r0n87e",
"first_available_date": "2016-06-21",
"availability": [
{
"start": "2016-06-21",
"end": "2016-08-01"
},
{
"start": "2016-08-20",
"end": "2016-08-28"
},
{
"start": "2016-10-03",
"end": "2016-11-02"
},
{ //This means it is available only for one day.
"start": "2016-11-13",
"end": "2016-11-13"
},
{
"start": "2016-11-28",
"end": "2017-01-14"
}
],
"apartment_metadata1": 56456,
"apartment_metadata2": 8989,
"status": "active"
},
{
"_id": "hgk87783iii86937jh",
"first_available_date": "2016-06-09",
"availability": [
{
"start": "2016-06-09",
"end": "2016-07-02"
},
{
"start": "2016-07-21",
"end": "2016-12-19"
},
{
"start": "2016-12-12",
"end": "2017-07-02"
}
],
"apartment_metadata1": 23534,
"apartment_metadata2": 24377,
"status": "active"
}
]
我想搜索那些可用于特定日期范围的公寓(比如2016-08-20 to 2016-12-12
)。然后
范围应属于各公寓的可用日期范围之一。
所以我想编写一个查询,例如:
{
"query": {
"bool": {
"must": [
{
"range": { "first_available_date": {"lte": "2016-08-20"} },
"match": { "status": "active" }
}
]
},
"filter": [
{
"range":
{
"apartments.availability.start": {"gte": "2016-08-20"},
"apartments.availability.end": {"lte": "2016-12-12"}
}
}
]
}
}
}
以上查询将返回两个公寓(与条件匹配的MULTIPLE availability
个对象),
这是不正确的,它应该仅返回带有_id: hgk87783iii86937jh
的文档,因为有一个availability
对象与creiteria完全匹配,即{"start": "2016-07-21", "end": "2016-12-19"}
。因此,为了获得正确的结果,条件应该是 - 在公寓doc中应该有一个availability
对象
这应该符合条件。那么如何强制执行上述查询中应该只有一个匹配?第二个问题 - 我的查询是否正确?
答案 0 :(得分:1)
使用nested query可以让您实现上述目标。
使用inner-hits获取匹配的availability-block
。
以下是实现此目的的示例:
创建索引
put testindex
{
"mappings": {
"data" : {
"properties": {
"availability" : {
"type": "nested"
}
}
}
}
}
索引数据:
put testindex/data/1
{
"first_available_date": "2016-06-21",
"availability": [
{
"start": "2016-06-21",
"end": "2016-08-01"
},
{
"start": "2016-08-20",
"end": "2016-08-28"
},
{
"start": "2016-10-03",
"end": "2016-11-02"
},
{
"start": "2016-11-13",
"end": "2016-11-13"
},
{
"start": "2016-11-28",
"end": "2017-01-14"
},
{
"start": "2016-07-21",
"end": "2016-12-19"
}
],
"apartment_metadata1": 4234,
"apartment_metadata2": 687878,
"status": "active"
}
<强>查询:强>
post testindex/data/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"first_available_date": {
"lte": "2016-08-20"
}
}
},
{
"match": {
"status": "active"
}
}
],
"filter": [
{
"nested": {
"path": "availability",
"query": {
"bool": {
"must": [
{
"range": {
"availability.start": {
"lte": "2016-08-20"
}
}
},
{
"range": {
"availability.end": {
"gte": "2016-12-12"
}
}
}
]
}
},
"inner_hits": {}
}
}
]
}
}
}
<强>结果:强>
"hits": {
"total": 1,
"max_score": 1.4142135,
"hits": [
{
"_index": "testindex",
"_type": "data",
"_id": "1",
"_score": 1.4142135,
"_source": {
"first_available_date": "2016-06-21",
"availability": [
{
"start": "2016-06-21",
"end": "2016-08-01"
},
{
"start": "2016-08-20",
"end": "2016-08-28"
},
{
"start": "2016-10-03",
"end": "2016-11-02"
},
{
"start": "2016-11-13",
"end": "2016-11-13"
},
{
"start": "2016-11-28",
"end": "2017-01-14"
},
{
"start": "2016-07-21",
"end": "2016-12-19"
}
],
"apartment_metadata1": 4234,
"apartment_metadata2": 687878,
"status": "active"
},
"inner_hits": {
"availability": {
"hits": {
"total": 1,
"max_score": 1.4142135,
"hits": [
{
"_index": "testindex",
"_type": "data",
"_id": "1",
"_nested": {
"field": "availability",
"offset": 5
},
"_score": 1.4142135,
"_source": {
"start": "2016-07-21",
"end": "2016-12-19"
}
}
]
}
}
}
}
]
}