使用 COLLECT 和 COLLECT AGGREGATE 在 ArangoDB 中搜索大型数据集

问题描述

我想提高一些自定义查询性能,目标是每天更新大多数用户的组。 这是一个由 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
  }