我正在构建一个小型应用程序,以使用Elasticsearch 6.8.0查找诸如booking.com这样的酒店客房可用性。
基本上,我每天和每个房间都有一个文档,其中指定了是否可用以及当天的价格。我需要运行具有以下要求的查询:
输入:
输出:
文件架构:
{
"mappings": {
"_doc": {
"properties": {
"room_id": {
"type": "keyword"
},
"available": {
"type": "boolean"
},
"rate": {
"type": "float"
},
"hotel_id": {
"type": "keyword"
},
"day": {
"type": "date",
"format": "yyyyMMdd"
}
}
}
}
}
我每个月都有一个索引,此刻我仅在同一个月内进行搜索。
我想出了这个查询:
GET /hotels_201910/_search?filter_path=aggregations.hotel.buckets.min_price.value,aggregations.hotel.buckets.key
{
"size": 0,
"query": {
"bool": {
"filter": [
{
"range": {
"day": { "gte" : "20191001", "lte" : "20191010" }
}
},
{
"term": {
"available": true
}
}
]
}
},
"aggs": {
"hotel": {
"terms": {
"field": "hotel_id",
"min_doc_count": 1,
"size" : 1000000
},
"aggs": {
"room": {
"terms": {
"field": "room_id",
"min_doc_count": 10,
"size" : 1000000
},
"aggs": {
"sum_price": {
"sum": {
"field": "rate"
}
},
"max_price": {
"bucket_selector": {
"buckets_path": {
"price": "sum_price"
},
"script": "params.price <= 600"
}
}
}
},
"min_price": {
"min_bucket": {
"buckets_path": "room>sum_price"
}
},
"sort_by_min_price" : {
"bucket_sort" :{
"sort": [{"min_price" : { "order" : "asc" }}],
"from" : 0,
"size" : 20
}
}
}
}
}
}
它有效,但是有几个问题。
"size"
设置为大量,否则,不会考虑所有酒店和房间。 有没有办法改善这种聚合的性能?我试图将索引拆分为多个分片,但这没有帮助。
我几乎可以肯定这种方法是错误的,这就是为什么速度很慢。关于在这种情况下如何实现更快的查询响应时间的任何建议?
最佳答案
在找到答案之前,我不明白您为什么使用以下条件/汇总
"min_price": {
"min_bucket": {
"buckets_path": "room>sum_price"
}
}
您能否进一步说明为什么需要此服务。
现在,回答您的主要问题:
为什么要同时用room_id和hotel_id来表示。您可以获取搜索的所有房间,然后在应用程序端按hotel_id对其进行分组。
以下逻辑将为您提供按room_id分组并具有总和指标的所有文档。您可以对> 600个条件使用相同的脚本过滤器。
{
"size": 0,
"query": {
"bool": {
"filter": [
{
"range": {
"day": { "gte" : "20191001", "lte" : "20191010" }
}
},
{
"term": {
"available": true
}
}
]
}
},
"by_room_id": {
"composite" : {
"size": 100,
"sources" : [
{
"room_id": {
"terms" : {
"field": "room_id"
}
}
}
]
},
"aggregations": {
"price_on_required_dates": {
"sum": { "field": "rate" }
},
"include_source": {
"top_hits": {
"size": 1,
"_source": true
}
},
"price_bucket_sort": {
"bucket_sort": {
"sort": [
{"price_on_required_dates": {"order": "desc"}}
]
}
}
}
}
}
另外,为了提高搜索效果,
https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-search-speed.html