MongoDB按国家分组统计各城市数量的查询实现问题
实现MongoDB国家-城市层级计数统计方案
没问题!要实现这种国家-城市层级的计数统计,用MongoDB的聚合框架就能完美搞定,我给你一步步拆解方案:
完整聚合查询代码
db.yourCollectionName.aggregate([ // 1. 统计每个国家下每个城市的出现次数 { $group: { _id: { country: "$country", city: "$city" }, count: { $sum: 1 } } }, // 2. 按国家分组,将城市与计数整理为键值对数组 { $group: { _id: "$_id.country", cityEntries: { $push: { k: "$_id.city", v: "$count" } } } }, // 3. 将城市键值对数组转换为对象格式 { $project: { _id: 0, countryKey: "$_id", cityCounts: { $arrayToObject: "$cityEntries" } } }, // 4. 聚合所有国家的统计结果为一个对象 { $group: { _id: null, dataEntries: { $push: { k: "$countryKey", v: "$cityCounts" } } } }, // 5. 替换根节点,生成最终期望的结构 { $replaceRoot: { newRoot: { data: { $arrayToObject: "$dataEntries" } } } } ])
各步骤详解
- 第一步:通过
$group同时按country和city分组,用$sum:1统计每组的出现次数,得到每个国家-城市组合的基础计数。 - 第二步:再次按
country分组,用$push将每个城市的键(k)和计数(v)收集为数组,为后续转对象做准备。 - 第三步:用
$arrayToObject将城市的键值对数组转换为{城市名: 计数}的对象格式,同时提取国家作为后续的键。 - 第四步:将所有国家的统计结果收集为一个键值对数组,键是国家名,值是对应的城市计数对象。
- 第五步:用
$arrayToObject将国家键值对数组转换为最终的嵌套对象,再通过$replaceRoot生成你需要的data包裹结构。
注意事项
记得把代码中的yourCollectionName替换成你实际的集合名称,执行后就能得到你期望的输出结果:
{ "data": { "US": {"NY": 2,"AL": 1,"MA": 2 }, "IN": {"DL": 3,"KA": 2 }} }
内容的提问来源于stack exchange,提问作者venu-n
相关产品推荐
相关产品推荐

