You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用AQL高效统计ArangoDB中多属性的PASS/FAIL数量?

ArangoDB大规模数据集多属性PASS/FAIL统计查询优化

需求说明

需编写AQL查询,对ArangoDB中的大规模测试数据集,按多个属性(如pull_force、cut_force等)分别统计PASS和FAIL的数量。

数据集示例

[
   {
     "workorder": "123456",
     "device_id": "1",
     "pull_force": "PASS",
     "cut_force": "PASS",
     "kpa_force": "FAIL",
     ...
   }
]

期望输出格式

{
  "pull_force": {
    "PASS": 300321, 
    "FAIL": 400
  },
  "cut_force": {
    "PASS": 300211, 
    "FAIL": 200
  },
  ...
}

当前实现及问题

当前实现会多次遍历数据集提取各属性数据,再分别过滤统计,当属性较多时查询效率极低:

LET pull_force_data = mydataset[*].pull_force
LET cut_force_data = mydataset[*].cut_force
LET kpa_force_data = mydataset[*].kpa_force
...

RETURN {
   pull_force: {
      PASS: LENGTH(pull_force_data[* FILTER CURRENT == "PASS"]), 
      FAIL: LENGTH(pull_force_data[* FILTER CURRENT == "FAIL"])
   },
   cut_force: {
      PASS: LENGTH(cut_force_data[* FILTER CURRENT == "PASS"]), 
      FAIL: LENGTH(cut_force_data[* FILTER CURRENT == "FAIL"])
   },
   kpa_force: {
      PASS: LENGTH(kpa_force_data[* FILTER CURRENT == "PASS"]), 
      FAIL: LENGTH(kpa_force_data[* FILTER CURRENT == "FAIL"])
   },
   ...
}

注:原代码返回的是匹配数组,这里修正为用LENGTH()获取数量,贴合期望输出格式。

优化方案

核心思路是仅遍历数据集一次,在遍历过程中同时更新所有属性的统计计数,避免多次全表扫描。

固定属性的优化查询

适用于明确知道需要统计的属性列表的场景:

// 初始化统计结构,按需添加要统计的属性
LET initialStats = {
  pull_force: { PASS: 0, FAIL: 0 },
  cut_force: { PASS: 0, FAIL: 0 },
  kpa_force: { PASS: 0, FAIL: 0 },
  ... // 其他需统计的属性
}

// 单次遍历数据集,增量更新统计计数
LET finalStats = FOR doc IN mydataset
  LET updatedStats = MERGE_RECURSIVE(initialStats, {
    pull_force: {
      [doc.pull_force]: initialStats.pull_force[doc.pull_force] + 1
    },
    cut_force: {
      [doc.cut_force]: initialStats.cut_force[doc.cut_force] + 1
    },
    kpa_force: {
      [doc.kpa_force]: initialStats.kpa_force[doc.kpa_force] + 1
    },
    ... // 其他属性的更新逻辑
  })
  LET initialStats = updatedStats
  RETURN updatedStats

// 取遍历完成后的最终统计结果
RETURN finalStats[-1]

动态属性的灵活统计方案

适用于不确定需要统计的属性列表的场景,自动识别并统计目标字段:

LET finalStats = FOR doc IN mydataset
  // 提取所有测试属性,排除无需统计的字段(如workorder、device_id)
  LET testAttrs = FOR attr IN ATTRIBUTES(doc)
    FILTER attr NOT IN ["workorder", "device_id"]
    RETURN { [attr]: { [doc[attr]]: 1 } }
  
  // 合并当前文档的统计数据到全局结果
  LET currentUpdate = MERGE_RECURSIVE(testAttrs...)
  LET initialStats = MERGE_RECURSIVE(initialStats, currentUpdate, (left, right) => left + right)
  LET initialStats = IF_NULL(initialStats, currentUpdate)
  RETURN initialStats

// 取最终统计结果
RETURN finalStats[-1]

优化关键点

  1. 减少遍历次数:原方案每个属性触发一次全表扫描,属性越多开销越大;优化后仅扫描一次数据集,大幅降低IO消耗。
  2. 增量计数:遍历过程中直接累加计数,避免后续的过滤和长度计算操作。
  3. 无额外索引依赖:这类全表统计无需额外建立索引,避免索引维护开销。

内容的提问来源于stack exchange,提问作者Justin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 06:32:47