MongoDB如何按嵌套域名分组统计各层级用户数量?
MongoDB按域名分组统计各层级用户数量的查询语句
我的MongoDB数据库中有如下格式的数据集:
{"name": "Alex","domains": {"domain_1": 1,"domain_2": 1,"domain_3": 0}}, {"name": "Arthur","domains": {"domain_1": 1,"domain_2": 0,"domain_3": 3}}, {"name": "Paul","domains": {"domain_1": 0,"domain_2": 2,"domain_3": 3}}需要按域名名称分组,统计各层级对应的用户数量,期望输出格式如下:
{ "domain_1": { "level_0": 1, "level_1": 2, "level_2": 0, "level_3": 0 }, "domain_2": { "level_0": 1, "level_1": 1, "level_2": 1, "level_3": 0 }, "domain_3": { "level_0": 1, "level_1": 0, "level_2": 0, "level_3": 2 } }
解决方案
使用MongoDB聚合框架可以实现需求,以下是完整的查询语句:
db.collection.aggregate([ { $project: { domainEntries: { $objectToArray: "$domains" } } }, { $unwind: "$domainEntries" }, { $group: { _id: { domain: "$domainEntries.k", level: "$domainEntries.v" }, count: { $sum: 1 } } }, { $group: { _id: "$_id.domain", levels: { $push: { k: { $concat: ["level_", { $toString: "$_id.level" }] }, v: "$count" } } } }, { $addFields: { levels: { $mergeObjects: [ { level_0: 0, level_1: 0, level_2: 0, level_3: 0 }, { $arrayToObject: "$levels" } ] } } }, { $group: { _id: null, result: { $mergeObjects: { $arrayToObject: [[{ k: "$_id", v: "$levels" }]] } } } }, { $replaceRoot: { newRoot: "$result" } } ])
各阶段说明
- 转换domains为数组:用
$objectToArray把每个文档里的domains对象拆成[{k: 域名, v: 层级}]格式的数组,方便后续拆分统计。 - 展开数组:
$unwind将数组拆成独立文档,每个文档对应一个用户的某个域名层级记录。 - 按域名+层级统计用户数:第一次
$group聚合,统计每个域名下每个层级的用户数量。 - 按域名聚合层级数据:第二次
$group把同一域名的所有层级统计结果整理成键值对数组,为转成对象做准备。 - 补充缺失层级的默认值:通过
$mergeObjects把默认的level_0到level_3(值为0)和实际统计结果合并,确保每个域名都包含四个层级的统计。 - 合并为最终格式:第三次
$group把所有域名的统计结果合并成一个大对象,再用$replaceRoot将这个对象作为输出根文档,匹配期望的格式。
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

