ElasticSearch聚合策略及查询语句
- 距离计算与筛选最近10个文档:
- 使用
geo_distance
查询来计算文档与指定点的距离,并通过size
参数限制返回10个最近的文档。
- 假设指定点的坐标为
[lon, lat]
。
- 筛选过去一周内更新的文档:
- 使用
range
查询,对update_time
字段进行筛选,确保文档是在过去一周内更新的。假设update_time
是date
类型,可以使用now - 1w/w
来表示过去一周的时间范围。
- 加权计算综合得分并排序:
- 使用
script_score
查询来进行加权计算综合得分。这里假设popularity
字段为数值类型。
- 最终的查询语句示例如下:
{
"query": {
"bool": {
"filter": [
{
"range": {
"update_time": {
"gte": "now - 1w/w"
}
}
},
{
"geo_distance": {
"distance": "100km", // 可以设置一个较大的初始距离,确保能找到足够的文档
"geo_point": [lon, lat]
}
}
]
}
},
"sort": [
{
"_script": {
"type": "number",
"script": {
"source": "doc['popularity'].value",
"lang": "painless"
},
"order": "desc"
}
}
],
"size": 10
}
大数据量下可能出现的性能瓶颈及调优措施
- 性能瓶颈:
- 地理空间计算开销大:在大数据量下,计算每个文档与指定点的距离会消耗大量的CPU和内存资源。
- 范围查询性能:
range
查询在大数据量下,尤其是在没有合适索引的情况下,可能会导致全表扫描,影响查询效率。
- 加权计算:
script_score
计算在大数据量时,由于需要对每个匹配文档执行脚本,可能会成为性能瓶颈。
- 调优措施:
- 地理空间索引优化:确保
geo_point
字段有合适的地理空间索引。例如,使用geo - shape
或geo - hash
等方式对地理空间数据进行索引,能够加快距离计算和筛选的速度。
- 时间字段索引:对
update_time
字段创建索引,使range
查询能够利用索引快速定位符合条件的文档,避免全表扫描。
- 减少脚本计算:如果可能,尽量避免在
script_score
中进行复杂计算。可以预先计算加权值并存储在文档中,直接使用存储的字段进行排序,减少实时计算开销。
- 分页优化:如果需要进行分页操作,避免使用
from + size
的方式,因为这种方式在大数据量下性能很差。可以使用scroll
或者search_after
来进行分页,减少内存和网络开销。