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

如何使用MongoDB aggregate实现用户多数组字段的批量计数

单次查询实现多数组字段统计方案

可以通过一次MongoDB聚合查询完成所有字段的统计需求,不需要重复发起多次请求,实现代码如下:

db.getCollection('users').aggregate([
  // 收集所有文档对应数组字段的内容
  {
    $group: {
      _id: null,
      fruits: { $push: { $ifNull: ["$fruits", []] } },
      colors: { $push: { $ifNull: ["$colors", []] } },
      habit: { $push: { $ifNull: ["$habit", []] } }
    }
  },
  // 把每个字段收集到的二维数组合并为一维数组
  {
    $project: {
      _id: 0,
      fruits: {
        $reduce: {
          input: "$fruits",
          initialValue: [],
          in: { $concatArrays: ["$$value", "$$this"] }
        }
      },
      colors: {
        $reduce: {
          input: "$colors",
          initialValue: [],
          in: { $concatArrays: ["$$value", "$$this"] }
        }
      },
      habit: {
        $reduce: {
          input: "$habit",
          initialValue: [],
          in: { $concatArrays: ["$$value", "$$this"] }
        }
      }
    }
  },
  // 按要求格式生成统计结果
  {
    $project: {
      fruits: {
        hasBanana: { $size: { $filter: { input: "$fruits", cond: { $eq: ["$$this", "banana"] } } } },
        hasApple: { $size: { $filter: { input: "$fruits", cond: { $eq: ["$$this", "apple"] } } } },
        hasPineapple: { $size: { $filter: { input: "$fruits", cond: { $eq: ["$$this", "pineapple"] } } } },
        // 其他水果的统计项按相同规则补充即可
      },
      colors: {
        hasRed: { $size: { $filter: { input: "$colors", cond: { $eq: ["$$this", "red"] } } } },
        hasBlue: { $size: { $filter: { input: "$colors", cond: { $eq: ["$$this", "blue"] } } } },
        hasGreen: { $size: { $filter: { input: "$colors", cond: { $eq: ["$$this", "green"] } } } },
        // 其他颜色的统计项按相同规则补充即可
      },
      habit: {
        hasRead: { $size: { $filter: { input: "$habit", cond: { $eq: ["$$this", "read"] } } } },
        hasSing: { $size: { $filter: { input: "$habit", cond: { $eq: ["$$this", "sing"] } } } },
        hasSleep: { $size: { $filter: { input: "$habit", cond: { $eq: ["$$this", "sleep"] } } } },
        // 其他习惯的统计项按相同规则补充即可
      }
    }
  }
])

如果不需要提前枚举要统计的元素,想要动态统计所有出现过的元素的次数,可以使用以下实现逻辑(以fruits字段为例,其他字段可同理扩展):

db.getCollection('users').aggregate([
  { $unwind: "$fruits" },
  { $group: { _id: "$fruits", count: { $sum: 1 } } },
  {
    $group: {
      _id: null,
      fruits: {
        $push: {
          k: { $concat: ["has", { $toUpper: { $substrCP: ["$_id", 0, 1] } }, { $substrCP: ["$_id", 1, { $strLenCP: "$_id" }] }] },
          v: "$count"
        }
      }
    }
  },
  { $project: { _id: 0, fruits: { $arrayToObject: "$fruits" } } }
])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 07:06:00