MongoDB查询对象数组内字段范围并过滤返回符合条件的数组元素
问题排查
- 语法错误:聚合方法调用拼写错误,应为
db.collection.aggregate,缺少集合名与方法名之间的点。 - 字段名不匹配:
details子文档的时间字段为day,但$filter条件中错误使用了不存在的date字段,导致所有数组元素都被过滤,最终返回空结果。 - 范围逻辑不符合需求:你需要返回
day值在1到3之间(包含两端)的元素,现有逻辑$gt: 1(大于1)会排除day=1的元素,$lt: 3(小于3)会排除day=3的元素,和预期要求不符。 - 投影字段不全:
$project配置中仅保留了_id和details字段,会丢失原文档的data、someMoreField等其他字段,不符合预期返回结构。 - 额外问题:
$match阶段的'details.day': { $gt: 1, $lte: 3 }条件会过滤掉所有details数组中没有符合条件元素的文档,如果你需要即使没有符合条件的元素也返回文档仅details为空,可以删除该过滤条件,交给后续$filter处理即可。
正确实现方案
使用$addFields代替$project,可以保留原文档所有字段,仅更新过滤后的details数组:
db.collection.aggregate([ { $match: { _id: 123 // 此处替换为你实际的查询id变量即可 } }, { $addFields: { details: { $filter: { input: "$details", as: "item", cond: { $and: [ { $gte: ["$$item.day", 1] }, { $lte: ["$$item.day", 3] } ] } } } } } ])
如果你需要使用$project方式,需要手动声明所有需要保留的字段:
db.collection.aggregate([ { $match: { _id: 123 } }, { $project: { _id: 1, data: 1, someMoreField: 1, details: { $filter: { input: "$details", as: "item", cond: { $and: [ { $gte: ["$$item.day", 1] }, { $lte: ["$$item.day", 3] } ] } } } } } ])
内容的提问来源于stack exchange,提问作者Totoro
相关产品推荐
相关产品推荐

