面试题答案
一键面试设计思路
- 分组统计:利用聚合(Aggregation)功能,按照业务需求的不同条件对数据进行分组,比如按照某个字段的值进行分组。
- 自定义计算字段:使用脚本字段(Scripted Field)在查询结果中添加自定义计算的字段。
- 避免性能瓶颈:
- 定制查询结构:避免复杂度过高的嵌套查询,合理规划查询的层级结构。对于聚合操作,尽量减少不必要的子聚合。
- 优化配置:调整Elasticsearch集群的配置参数,如增加节点资源(内存、CPU等),合理设置分片数量和副本数量,避免单个分片数据量过大。
DSL实现示例
假设我们有一个索引,其中文档包含 category
(分类)字段和 price
(价格)字段,业务需求是按 category
分组统计平均价格,并添加一个自定义字段表示价格与平均价格的差值。
{
"size": 0,
"aggs": {
"category_groups": {
"terms": {
"field": "category"
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
},
"price_difference": {
"bucket_script": {
"buckets_path": {
"avg_price": "avg_price"
},
"script": "doc['price'].value - params.avg_price"
}
}
}
}
}
}
size: 0
:表示我们只关心聚合结果,不返回具体的文档。terms
聚合:按category
字段进行分组。avg
聚合:在每个分组内计算price
字段的平均价格。bucket_script
管道聚合:计算每个文档价格与平均价格的差值作为自定义字段。
原理
- 聚合:Elasticsearch通过在各个分片上执行局部聚合,然后将结果合并到协调节点上,最终得出全局聚合结果。
- 脚本字段:
bucket_script
允许在聚合桶的上下文中执行脚本计算,buckets_path
用于引用其他聚合的结果,script
部分则是具体的计算逻辑。通过这种方式,可以根据已有字段和聚合结果计算出新的字段。 - 避免性能瓶颈原理:
- 定制查询结构:简单清晰的查询结构能减少Elasticsearch在解析和执行查询时的资源消耗。
- 优化配置:增加节点资源能提升集群整体处理能力;合理设置分片和副本数量能平衡数据分布和读写性能,避免因数据倾斜或单个分片负载过高导致性能下降。