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

MongoDB如何分组不同键的值并统计0/0、0/1的出现次数?

解决MongoDB动态键分组及0/0、0/1次数统计问题

没问题,这种动态键的分组统计确实有点 tricky,但MongoDB的聚合管道完全能搞定!先假设你的文档结构大概是这样的(方便后续演示):

{
  "_id": ObjectId("60d21b4667d0d8992e610c85"),
  "samples": {
    "sensor_202": [0, 0],
    "sensor_317": [0, 1],
    "sensor_459": [1, 0],
    "sensor_108": [0, 0]
  }
}

下面是针对这个场景的聚合方案,我会一步步拆解每个阶段的作用:

完整聚合管道命令

db.yourCollection.aggregate([
  // 第一步:把samples对象转成键值对数组,统一处理动态键
  {
    $addFields: {
      sampleEntries: { $objectToArray: "$samples" }
    }
  },
  // 第二步:展开数组,让每个键值对成为独立文档
  { $unwind: "$sampleEntries" },
  // 第三步:提取值数组的两个元素,拼接成我们要统计的模式(比如"0/0")
  {
    $addFields: {
      pattern: {
        $concat: [
          { $toString: { $arrayElemAt: ["$sampleEntries.v", 0] } },
          "/",
          { $toString: { $arrayElemAt: ["$sampleEntries.v", 1] } }
        ]
      }
    }
  },
  // 第四步:按模式分组,统计出现次数
  {
    $group: {
      _id: "$pattern",
      count: { $sum: 1 }
    }
  },
  // 可选:只保留你关心的0/0、0/1模式,过滤掉其他
  {
    $match: {
      _id: { $in: ["0/0", "0/1"] }
    }
  },
  // 可选:重命名_id为pattern,让结果更直观
  {
    $project: {
      _id: 0,
      pattern: "$_id",
      count: 1
    }
  }
])

各阶段详细解释

  • $addFields + $objectToArray:这是处理动态键的核心!$objectToArray会把samples这样的对象转换成[{k: "键名", v: "对应值"}]的数组,不管你的键叫什么,都能统一处理。
  • $unwind:把上面生成的数组展开,每个键值对单独成为一条文档,这样我们就能逐个处理每个键对应的值。
  • $addFields + $concat:从值数组(比如[0,0])里提取第一个和第二个元素,转成字符串后用/拼接成"0/0"这样的模式,方便后续分组统计。
  • $group:按拼接好的pattern分组,用$sum:1统计每个模式出现的总次数。
  • $match(可选):如果你只关心0/0和0/1,可以用这个阶段过滤掉其他模式的结果。
  • $project(可选):把默认的_id字段重命名为pattern,让最终结果的可读性更好。

注意事项

  • 如果你的samples里存在值不是长度为2的数组的情况(比如空数组、单元素数组),可以在$unwind之后加一个$match阶段过滤掉这些异常数据:
    { $match: { $expr: { $eq: [{ $size: "$sampleEntries.v" }, 2] } } }
    
  • 记得把db.yourCollection替换成你实际的集合名称哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:14:52