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

MongoDB技术问询:按object1分组统计选中与未选中对象出现次数

MongoDB聚合管道:按Object1统计选中/未选中次数

以下是实现需求的两种聚合管道方案,均能输出你期望的格式:

方案一:使用$facet并行统计(高效推荐)

这个方案通过$facet同时完成三类统计,避免多次遍历集合,性能更优:

db.your_collection_name.aggregate([
  // 1. 并行执行三个分组操作,分别统计选中次数、未选中次数,以及收集所有Object1的唯一值
  {
    $facet: {
      "selected_counts": [
        {
          $group: {
            _id: "$selected", // 替换为你实际的selected字段名,比如$selectedObject
            selected_count: { $sum: 1 }
          }
        }
      ],
      "unselected_counts": [
        {
          $group: {
            _id: "$Unselected", // 替换为你实际的unselected字段名,比如$unselectedObject
            unselected_count: { $sum: 1 }
          }
        }
      ],
      "object1_objects": [
        {
          $group: {
            _id: "$Object1" // 替换为你实际的object1字段名,比如$object1
          }
        }
      ]
    }
  },
  // 2. 将Object1的唯一值数组拆分为单个文档
  { $unwind: "$object1_objects" },
  // 3. 重命名字段为输出需要的格式
  {
    $project: {
      Object: "$object1_objects._id",
      selected_counts: 1,
      unselected_counts: 1
    }
  },
  // 4. 匹配当前Object对应的选中次数,无匹配则设为0
  {
    $addFields: {
      Selected: {
        $let: {
          vars: {
            matched: { $first: { $filter: { input: "$selected_counts", cond: { $eq: ["$$this._id", "$Object"] } } } }
          },
          in: { $ifNull: ["$$matched.selected_count", 0] }
        }
      }
    }
  },
  // 5. 匹配当前Object对应的未选中次数,无匹配则设为0
  {
    $addFields: {
      Unselected: {
        $let: {
          vars: {
            matched: { $first: { $filter: { input: "$unselected_counts", cond: { $eq: ["$$this._id", "$Object"] } } } }
          },
          in: { $ifNull: ["$$matched.unselected_count", 0] }
        }
      }
    }
  },
  // 6. 保留需要的输出字段,移除默认_id
  {
    $project: {
      _id: 0,
      Object: 1,
      Selected: 1,
      Unselected: 1
    }
  }
])

关键阶段说明

  • $facet:一次性完成三类统计任务,减少集合遍历次数;
  • $filter + $ifNull:实现统计数据的匹配与默认值填充,确保未出现的对象计数为0;
  • 最后一步$project:严格对齐期望的输出字段格式。

方案二:拆分文档后统计

这个方案通过拆分每个文档为选中、未选中两条记录,再统一统计:

db.your_collection_name.aggregate([
  // 1. 将每个文档拆分为两条记录,分别标记选中/未选中类型
  {
    $unionWith: {
      coll: "your_collection_name", // 替换为你的集合名
      pipeline: [
        { $project: { obj: "$selected", type: "selected", object1: "$Object1" } },
        { $project: { obj: "$Unselected", type: "unselected", object1: "$Object1" } }
      ]
    }
  },
  // 2. 收集所有Object1的唯一值及所有拆分后的记录
  {
    $group: {
      _id: null,
      object1_list: { $addToSet: "$object1" },
      all_records: { $push: "$$ROOT" }
    }
  },
  // 3. 遍历每个Object1对象,统计对应选中/未选中次数
  { $unwind: "$object1_list" },
  {
    $project: {
      Object: "$object1_list",
      Selected: {
        $size: {
          $filter: {
            input: "$all_records",
            cond: { $and: [{ $eq: ["$$this.obj", "$object1_list"] }, { $eq: ["$$this.type", "selected"] }] }
          }
        }
      },
      Unselected: {
        $size: {
          $filter: {
            input: "$all_records",
            cond: { $and: [{ $eq: ["$$this.obj", "$object1_list"] }, { $eq: ["$$this.type", "unselected"] }] }
          }
        }
      }
    }
  },
  // 4. 移除默认_id
  { $project: { _id: 0 } }
])

注意事项

  • 请将代码中的your_collection_name替换为你的实际集合名称;
  • 字段名需与你集合中的实际字段对齐:比如示例中的selected/Unselected/Object1,如果你的集合是selectedObject/unselectedObject/object1,请对应修改代码中的字段引用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 14:55:24