MongoDB如何移除仅含单个元素的嵌套数组
移除MongoDB中仅含单个元素的嵌套子数组
需求
从目标文档的yearDiff数组中移除所有仅包含单个对象的子数组,只保留元素数量大于1的子数组:
原始文档
[ { "_id": "102", "yearDiff": [ [ { "e_date": ISODate("2016-04-01T00:00:00Z"), "h_val": 4, "p_id": "102" } ], [ { "e_date": ISODate("2016-04-01T00:00:00Z"), "h_val": 5, "p_id": "102" } ], [ { "e_date": ISODate("2018-04-01T00:00:00Z"), "h_val": 6, "p_id": "102" }, { "d_val": 62, "e_date_1": ISODate("2004-09-01T00:00:00Z"), "p_id": "102", "s_val": 81 }, { "d_val": 62, "e_date_1": ISODate("2005-09-01T00:00:00Z"), "p_id": "102", "s_val": 81 } ] ] } ]
期望结果
[ { "e_date": ISODate("2018-04-01T00:00:00Z"), "h_val": 6, "p_id": "102" }, { "d_val": 62, "e_date_1": ISODate("2004-09-01T00:00:00Z"), "p_id": "102", "s_val": 81 }, { "d_val": 62, "e_date_1": ISODate("2005-09-01T00:00:00Z"), "p_id": "102", "s_val": 81 } ]
问题分析
你之前尝试的{"yearDiff.0.1.p_id":{$exists:true}}是用于过滤整个文档的条件,它只会返回第一个子数组包含第二个元素的文档,无法实现筛选yearDiff内部子数组的需求。
解决方案
使用MongoDB聚合管道,通过$filter筛选出长度大于1的子数组,再通过$unwind和$replaceRoot将结果转换为期望格式:
db.collection.aggregate([ // 筛选yearDiff中长度大于1的子数组 { $addFields: { yearDiff: { $filter: { input: "$yearDiff", cond: { $gt: [{ $size: "$$this" }, 1] } } } } }, // 展开筛选后的子数组 { $unwind: "$yearDiff" }, // 将子数组内容作为根文档返回 { $replaceRoot: { newRoot: "$yearDiff" } } ])
如果仅需保留筛选后的子数组(无需展开为根文档),可去掉后续的$unwind和$replaceRoot阶段,最终yearDiff字段会是仅包含符合条件子数组的数组。
内容的提问来源于stack exchange,提问作者Will Jue
相关产品推荐
相关产品推荐

