问题描述
我想提高一些自定义查询的性能,目标是每天更新大多数用户的组。 这是一个由 3 个主要集合组成的大型数据集:
- 用户(文档)
- 组(文档)
- 连接(边)
用户可以加入多个群组 (1:N)。 组可以有很多参与者 (N:1),女巫是用户或其他组。例如:fighter1 在 RaidParty1 中,RaidParty1 在 Guild1 中。
COLLECT party= user.partyID WITH COUNT INTO num_users
SORT num_users DESC
RETURN {"Party": party,"Num. Users" : num_users}
这在示例数据集中需要 4 毫秒,在完整数据集上需要超过 1 秒,并且非常占用内存。
我知道我可以使用类似的东西
FOR user IN userSample
COLLECT party= user.partyID WITH COUNT INTO num_users
COLLECT AGGREGATE max_num_users= MAX(num_users)
RETURN {"Top Guild": max_num_users}
但这并不是取消聚合优化,因为每次形成 num_users 都是耗时的部分。有没有办法同时收集和聚合?
奖励:有什么想法可以使它进入前 10 名吗?
解决方法
您可以将 WITH COUNT INTO
替换为 AGGREGATE
子句:
FOR user IN userSample
COLLECT party = user.partyID AGGREGATE num_users = LENGTH(1)
SORT num_users DESC
RETURN {
"Party": party,"Num. Users": num_users
}
然而,两种变体都导致完全相同的执行计划(至少在最新版本的 ArangoDB 中)。
如果我理解正确,那么您想计算每方的用户数,然后在这些计数中找到最大值。这对于单个 COLLECT
操作是不可能的:
聚合表达式不能引用 COLLECT 本身引入的变量
Grouping and aggregation with COLLECT in AQL | ArangoDB Documentation
对于前 10 名的列表,这应该有效:
FOR user IN userSample
COLLECT party = user.partyID WITH COUNT INTO num_users
SORT num_users DESC
LIMIT 10
RETURN {
"Party": party,"Num. Users": num_users
}