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

MongoDB 4.4聚合:按州分组去重嵌套城市值问题

MongoDB v4.4 按州分组生成去重城市列表解决方案

数据结构与需求

集合文档结构

每个文档包含addresses数组,示例:

"addresses": [
  {
    "state": "New York",
    "city": "New York"
  },
  {
    "state": "New York",
    "city": "Buffalo"
  },
  {
    "state": "Massachusetts",
    "city": "Boston"
  },
  ...
]

预期输出

跨所有文档生成按state分组的去重city列表:

[
  {
    "state": "New York",
    "cities": [
      "New York",
      "Buffalo"
    ]
  },
  {
    "state": "Massachusetts",
    "cities": [
      "Boston"
    ]
  },
  ...
]

现有查询问题分析

第一个查询仅返回部分州

执行以下聚合仅得到20个州(实际集合包含50个州):

db.locations.aggregate([
  { $unwind: {path: "$addresses" }},
  { $group: {
      _id: "$addresses.state",
      cities: { $addToSet: '$addresses.city' }
    }
  }
])

问题原因:查询逻辑本身正确,大概率是客户端工具默认分页(比如Mongo Shell默认只显示前20条),输入it命令即可加载剩余结果;也可能是你无意中添加了未提及的$match过滤条件。

第二个查询未按州分组

返回的州和城市存入两个无序数组,核心问题是$group的_id设置错误(比如设为null或固定值,导致所有数据聚合到同一组)。

正确聚合管道

以下代码可实现需求,完全匹配预期输出:

db.locations.aggregate([
  // 展开所有文档中的addresses数组,拆分每个地址为独立文档
  { $unwind: "$addresses" },
  // 按州分组,用$addToSet自动去重收集城市
  { $group: {
      _id: "$addresses.state",
      cities: { $addToSet: "$addresses.city" }
    }
  },
  // 重命名字段,让输出结构与预期一致
  { $project: {
      _id: 0,
      state: "$_id",
      cities: 1
    }
  },
  // 可选:按州名排序,结果更规整
  { $sort: { state: 1 } }
])

关键步骤说明

  • $unwind:确保每个地址条目都被单独处理,不会遗漏跨文档的州/城市组合
  • $group:以addresses.state为分组键,$addToSet自动过滤重复城市
  • $project:将分组用的_id重命名为state,移除多余的_id字段
  • 如果结果显示不全,在Mongo Shell中执行it命令加载下一页,直到无更多结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 01:47:45