【Elasticsearch】Geo-distance聚合
`geo_distance`聚合的形状是圆形。它基于一个中心点(`origin`)和一系列距离范围来计算每个文档与中心点的距离,并将文档分配到相应的距离范围内。这种聚合方式本质上是以中心点为圆心,以指定的距离范围为半径的圆形区域来划分数据。
为什么是圆形?
`geo_distance`聚合的核心是计算每个文档的地理位置与指定起点之间的直线距离(欧几里得距离或球面距离)。因此,它自然形成了以起点为中心的圆形区域。例如:
• 如果你指定一个范围是`0-10km`,那么所有距离起点在 10 公里以内的文档都会被归入这个范围。
• 这个范围在地理空间上就是一个以起点为中心、半径为 10 公里的圆形区域。
示例说明
假设我们有一个起点(`origin`)和以下距离范围:
• `0-10km`
• `10-50km`
• `50km`以上
这些范围在地理空间上可以表示为以下圆形区域:
• 第一个范围:以起点为中心,半径为 10 公里的圆内。
• 第二个范围:以起点为中心,半径在 10 公里到 50 公里之间的环形区域。
• 第三个范围:以起点为中心,半径大于 50 公里的区域。
圆形区域的可视化
以下是一个简单的示意图,展示这些圆形区域的划分:
```
起点 (origin)
|
|--- 10km 圆
| |
| |--- 50km 圆
| |
| |--- 50km 以上区域
|
```
与其他聚合的对比
• `geo_distance`聚合:基于圆形区域,以起点为中心,按距离划分。
• `geo_tile_grid`聚合:基于网格划分,将地理空间划分为规则的矩形网格。
• `geo_bounding_box`过滤器:基于矩形区域,限定一个矩形范围。
场景示例
假设你有一个包含多个餐厅的索引,你希望统计距离某个用户位置不同距离范围内的餐厅数量。使用`geo_distance`聚合可以实现这一点,它会根据用户位置形成圆形区域,统计每个区域内的餐厅数量。
示例代码
```json
POST /restaurants/_search?size=0
{
"aggs": {
"distance_ranges": {
"geo_distance": {
"field": "location",
"origin": "POINT (121.4737 31.2304)", <!-- 上海市中心 -->
"unit": "km",
"ranges": [
{ "to": 5 },
{ "from": 5, "to": 10 },
{ "from": 10 }
]
}
}
}
}
```
响应示例
```json
{
"aggregations": {
"distance_ranges": {
"buckets": [
{
"key": "*-5.0",
"from": 0.0,
"to": 5.0,
"doc_count": 10 <!-- 0-5公里范围内有10个餐厅 -->
},
{
"key": "5.0-10.0",
"from": 5.0,
"to": 10.0,
"doc_count": 8 <!-- 5-10公里范围内有8个餐厅 -->
},
{
"key": "10.0-*",
"from": 10.0,
"doc_count": 12 <!-- 10公里以上范围内有12个餐厅 -->
}
]
}
}
}
```
总结
`geo_distance`聚合的形状是圆形,它基于起点和距离范围划分数据。这种聚合方式非常适合用于地理空间分析,例如统计某个地点周围不同距离范围内的文档数量。