MST
星途 面试题库

面试题:ElasticSearch条件限制类decider在复杂聚合分析中的运用

在一个包含大量用户行为日志的ElasticSearch集群中,日志文档包含用户ID、行为类型、发生时间等字段。现在需要统计每个用户在过去一周内,不同行为类型的发生次数,并且只统计行为次数大于10次的用户及相应行为类型。请说明如何利用条件限制类decider来完成该复杂的聚合分析,并给出关键代码片段。
33.8万 热度难度
数据库ElasticSearch

知识考点

AI 面试

面试题答案

一键面试
  1. 利用条件限制类decider实现思路
    • 使用Elasticsearch的聚合功能,首先按用户ID进行分组,然后在每个用户组内再按行为类型分组,并统计每种行为类型的发生次数。
    • 通过bucket_selector这个条件限制类decider来过滤掉行为次数小于等于10次的结果。
  2. 关键代码片段(以Python的Elasticsearch DSL库为例)
from elasticsearch_dsl import Search, Q

# 创建Search对象
s = Search(using='your_connection', index='your_index')

# 限制时间范围为过去一周
now = datetime.now()
one_week_ago = now - timedelta(days = 7)
s = s.filter('range', 发生时间 = {'gte': one_week_ago, 'lt': now})

# 聚合操作
s.aggs.bucket('by_user', 'terms', field='用户ID') \
  .bucket('by_action_type', 'terms', field='行为类型') \
  .metric('action_count', 'value_count')

# 使用bucket_selector过滤行为次数大于10次的用户及行为类型
s.aggs['by_user'].bucket('filtered_actions', 'bucket_selector',
    buckets_path = {'count': 'by_action_type>action_count'},
    script = 'params.count > 10'
)

# 执行搜索
response = s.execute()

# 处理结果
for user_bucket in response.aggregations.by_user.buckets:
    user_id = user_bucket.key
    for action_bucket in user_bucket.filtered_actions.buckets:
        action_type = action_bucket.key
        action_count = action_bucket.by_action_type.action_count.value
        print(f"用户ID: {user_id}, 行为类型: {action_type}, 行为次数: {action_count}")

在上述代码中:

  • 首先通过range过滤器限制时间范围。
  • 然后通过terms聚合分别按用户ID和行为类型进行分组,并使用value_count统计每种行为类型的发生次数。
  • 最后通过bucket_selectorscriptbuckets_path来过滤掉行为次数小于等于10次的结果,并输出符合条件的用户ID、行为类型及行为次数。

如果是使用Elasticsearch的原生查询DSL(JSON格式),关键聚合部分如下:

{
    "aggs": {
        "by_user": {
            "terms": {
                "field": "用户ID"
            },
            "aggs": {
                "by_action_type": {
                    "terms": {
                        "field": "行为类型"
                    },
                    "aggs": {
                        "action_count": {
                            "value_count": {
                                "field": "行为类型"
                            }
                        }
                    }
                },
                "filtered_actions": {
                    "bucket_selector": {
                        "buckets_path": {
                            "count": "by_action_type>action_count"
                        },
                        "script": "params.count > 10"
                    }
                }
            }
        }
    }
}

此JSON DSL同样实现了按用户ID分组,再按行为类型分组统计次数,并过滤掉行为次数小于等于10次的结果。