MongoDB 4.4亿级集合嵌套数组重复a.p.id高效匹配方案
高效查找嵌套数组中存在重复ID的MongoDB文档方案
问题背景
现有MongoDB集合包含超1亿条文档,文档结构示例如下:
{ "key": 1, "a": [ { "p": [ { "id": 2 }, { "id": 3 } ] } ] }, { "key": 2, "a": [ { "p": [ { "id": 4 }, { "id": 3 } ] } ] }
需要找出所有包含重复a.p.id值的文档,最终输出格式为{ id:3 , key:[1,2] },要求禁止使用$unwind(两次$unwind在大数据量下性能极差),基于MongoDB 4.4版本的聚合框架实现。
解决方案
通过聚合框架的数组操作符直接提取并统计所有a.p.id的出现情况,无需展开嵌套数组:
- 扁平化提取ID:用
$reduce和$concatArrays将嵌套的a.p.id整理为一维数组 - 筛选重复文档:对比去重前后的数组长度,筛选出包含重复ID的文档
- 关联ID与key:将每个ID和所属文档的
key映射为独立条目,最后按ID分组聚合结果
完整聚合代码
db.collection.aggregate([ { $addFields: { allIds: { $reduce: { input: "$a", initialValue: [], in: { $concatArrays: ["$$value", "$$this.p.id"] } } } } }, { $match: { $expr: { $lt: [{ $size: { $setUnion: ["$allIds"] } }, { $size: "$allIds" }] } } }, { $addFields: { idKeys: { $map: { input: "$allIds", as: "id", in: { id: "$$id", key: "$key" } } } } }, { $unwind: "$idKeys" }, { $group: { _id: "$idKeys.id", key: { $addToSet: "$idKeys.key" } } }, { $match: { $expr: { $gte: [{ $size: "$key" }, 2] } } }, { $project: { _id: 0, id: "$_id", key: 1 } } ])
性能说明
- 仅对扁平化后的
idKeys做一次$unwind,避免了嵌套数组两次展开的性能损耗 - 利用MongoDB 4.4原生数组操作符处理嵌套结构,降低内存占用
- 若数据量极大,建议为
a.p.id建立多键索引,进一步提升ID提取效率
内容的提问来源于stack exchange,提问作者R2D2
相关产品推荐
相关产品推荐

