MST
星途 面试题库

面试题:ElasticSearch聚合功能之专家难度

在一个ElasticSearch集群中,有一个大规模的索引数据,包含各种复杂的业务数据。现在要基于多个条件嵌套聚合,比如先按地区(region)聚合,然后在每个地区内按年龄段(age_group)聚合,同时在每个年龄段聚合内还要计算不同性别(gender)的某个数值型字段(value)的加权平均值,权重是另一个字段(weight)。并且要求在聚合结果中筛选出加权平均值大于某个阈值(如100)的年龄段聚合。请设计完整的解决方案,包括可能涉及到的性能优化措施,并写出精确的DSL语句。
50.5万 热度难度
数据库ElasticSearch

知识考点

AI 面试

面试题答案

一键面试

1. 设计完整的解决方案

  1. 嵌套聚合设计:利用Elasticsearch的聚合功能,按照题目要求进行多层嵌套聚合。先按region聚合,然后在每个region聚合结果内按age_group聚合,最后在每个age_group聚合内按gender聚合并计算value字段的加权平均值。
  2. 筛选条件:在age_group聚合结果中,使用bucket_selector来筛选出加权平均值大于阈值(如100)的聚合。
  3. 性能优化措施
    • 数据建模优化:确保索引字段有合适的映射,特别是数值型字段和参与聚合的字段,合理设置doc_values等参数以提升聚合性能。
    • 缓存:利用Elasticsearch的缓存机制,例如filter缓存,如果查询条件中有固定的过滤条件,可以利用缓存来减少重复计算。
    • 分片优化:合理设置索引的分片数量,确保数据均匀分布在各个分片上,避免数据倾斜,提高聚合计算的并行度。

2. DSL语句

{
    "size": 0,
    "aggs": {
        "by_region": {
            "terms": {
                "field": "region.keyword",
                "size": 100
            },
            "aggs": {
                "by_age_group": {
                    "terms": {
                        "field": "age_group.keyword",
                        "size": 100
                    },
                    "aggs": {
                        "weighted_avg_by_gender": {
                            "weighted_avg": {
                                "value": {
                                    "field": "value"
                                },
                                "weight": {
                                    "field": "weight"
                                }
                            }
                        },
                        "filter_weighted_avg": {
                            "bucket_selector": {
                                "buckets_path": {
                                    "avg_value": "weighted_avg_by_gender"
                                },
                                "script": "params.avg_value > 100"
                            }
                        }
                    }
                }
            }
        }
    }
}

解释:

  • size: 0 表示不返回文档,只返回聚合结果。
  • by_region 是按region进行terms聚合。
  • by_age_group 是在每个region聚合结果内按age_group进行terms聚合。
  • weighted_avg_by_gender 是在每个age_group聚合内按gender计算value字段的加权平均值。
  • filter_weighted_avg 使用bucket_selector筛选出加权平均值大于100的age_group聚合。