【发布时间】:2020-07-21 02:30:12
【问题描述】:
我有一个包含用户位置的弹性搜索索引。 我需要使用 geohash 网格对地理边界框执行聚合查询,对于文档计数小于某个值的存储桶,我需要返回所有文档。
我该怎么做?
【问题讨论】:
-
到目前为止你尝试了什么?
标签: elasticsearch elasticsearch-aggregation elasticsearch-query
我有一个包含用户位置的弹性搜索索引。 我需要使用 geohash 网格对地理边界框执行聚合查询,对于文档计数小于某个值的存储桶,我需要返回所有文档。
我该怎么做?
【问题讨论】:
标签: elasticsearch elasticsearch-aggregation elasticsearch-query
由于您没有提供有关您创建的索引和用户位置的任何相关信息。
我正在考虑以下数据:
索引定义
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
索引示例文档
POST _bulk
{"index":{"_id":1}}
{"location":"52.37408,4.912350","name":"The golden dragon"}
{"index":{"_id":2}}
{"location":"52.369219,4.901618","name":"Burger King"}
{"index":{"_id":3}}
{"location":"52.371667,4.914722","name":"Wendys"}
{"index":{"_id":4}}
{"location":"51.222900,4.405200","name":"Taco Bell"}
{"index":{"_id":5}}
{"location":"48.861111,2.336389","name":"McDonalds"}
{"index":{"_id":6}}
{"location":"48.860000,2.327000","name":"KFC"}
根据您的问题:
当请求详细的存储桶时,使用像
geo_bounding_box这样的过滤器 应适用于缩小主题范围
想了解更多,可以参考这个official ES doc
doc_count 的数据,我们可以使用bucket_selector 管道聚合。管道聚合作用于其他产生的输出 聚合而不是来自文档集,将信息添加到 输出树。
因此,计算 doc_count 所需完成的工作量将是相同的。
查询
{
"aggs": {
"location": {
"filter": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 52.5225,
"lon": 4.5552
},
"bottom_right": {
"lat": 52.2291,
"lon": 5.2322
}
}
}
},
"aggs": {
"around_amsterdam": {
"geohash_grid": {
"field": "location",
"precision": 8
},
"aggs": {
"the_filter": {
"bucket_selector": {
"buckets_path": {
"the_doc_count": "_count"
},
"script": "params.the_doc_count < 2"
}
}
}
}
}
}
}
}
搜索结果
"hits": {
"total": {
"value": 6,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "restaurant",
"_type": "_doc",
"_id": "1",
"_score": 1.0,
"_source": {
"location": "52.37408,4.912350",
"name": "The golden dragon"
}
},
{
"_index": "restaurant",
"_type": "_doc",
"_id": "2",
"_score": 1.0,
"_source": {
"location": "52.369219,4.901618",
"name": "Burger King"
}
},
{
"_index": "restaurant",
"_type": "_doc",
"_id": "3",
"_score": 1.0,
"_source": {
"location": "52.371667,4.914722",
"name": "Wendys"
}
},
{
"_index": "restaurant",
"_type": "_doc",
"_id": "4",
"_score": 1.0,
"_source": {
"location": "51.222900,4.405200",
"name": "Taco Bell"
}
},
{
"_index": "restaurant",
"_type": "_doc",
"_id": "5",
"_score": 1.0,
"_source": {
"location": "48.861111,2.336389",
"name": "McDonalds"
}
},
{
"_index": "restaurant",
"_type": "_doc",
"_id": "6",
"_score": 1.0,
"_source": {
"location": "48.860000,2.327000",
"name": "KFC"
}
}
]
},
"aggregations": {
"location": {
"doc_count": 3,
"around_amsterdam": {
"buckets": [
{
"key": "u173zy3j",
"doc_count": 1
},
{
"key": "u173zvfz",
"doc_count": 1
},
{
"key": "u173zt90",
"doc_count": 1
}
]
}
}
}
}
它将根据"params.the_doc_count < 2"过滤掉所有计数小于2的文档
【讨论】: