MongoDB如何查询嵌套数组中like类型元素超2个的完整文档
解决MongoDB聚合查询返回完整文档字段的问题
刚好我之前处理过类似的需求,你的原聚合语句虽然能筛选出符合条件的文档,但因为$unwind和$group的操作丢失了原文档的其他字段。这里给你两种可行的解决方案,优先推荐第一种,因为它性能更优且能完整保留所有原字段:
方案一:使用$filter+$size统计(推荐)
MongoDB 3.4已经支持$filter和$size操作符,我们可以直接在文档层面统计facebookEvents中type为"like"的元素数量,不需要拆分数组,这样能完整保留原文档的所有字段:
db.getCollection('customerData').aggregate([ // 新增likeCount字段,统计like类型的事件数量 { $addFields: { likeCount: { $size: { $filter: { input: "$facebookEvents", as: "event", cond: { $eq: ["$$event.type", "like"] } } } } } }, // 筛选出like数量超过2的文档 { $match: { likeCount: { $gt: 2 } } }, // 可选:如果不需要保留likeCount字段,添加此步骤删除它 // { // $project: { // likeCount: 0 // } // } ])
这个方案的好处是:
- 不需要拆分数组,避免了
$unwind带来的性能开销 - 完整保留原文档的所有字段(包括
Name、companyID、完整的facebookEvents数组) - 逻辑清晰,代码更简洁
方案二:修改原聚合保留字段(不推荐,仅作参考)
如果你坚持要用原有的unwind+group思路,需要在$group阶段把需要的字段通过$first(因为同一个_id的文档这些字段值都相同)保留下来,但注意这种方式无法还原完整的facebookEvents数组(因为$unwind已经把数组拆成了单个元素):
db.getCollection('customerData').aggregate([ { $project : { 'companyID' : 1, 'facebookEvents' : 1,'Name':1 } }, { $unwind : "$facebookEvents" }, { $match : { 'facebookEvents.type' : { $eq: 'like' } } }, { $group : { _id : "$_id", likes : { $sum : 1}, // 保留原文档的字段 companyID: { $first: "$companyID" }, Name: { $first: "$Name" }, // 注意:这里只能拿到单个like类型的event,不是原数组 sampleLikeEvent: { $first: "$facebookEvents" } } }, {$match:{likes:{$gt:2}}} ])
显然这种方案有局限性,所以优先选择方案一。
内容的提问来源于stack exchange,提问作者Channa
相关产品推荐
相关产品推荐

