MongoDB复杂数组查询:如何检索符合特定条件的文档?
MongoDB 查询实现方案
要满足你提出的两个查询条件,可以通过MongoDB的聚合管道来实现,具体内容如下:
聚合查询语句
db.collection.aggregate([ // 第一步:过滤counter小于201的文档,减少后续计算量 { $match: { counter: { $lt: 201 } } }, // 第二步:从values数组中筛选出date最大的元素 { $addFields: { latestValue: { $reduce: { input: "$values", initialValue: { date: ISODate("1970-01-01T00:00:00Z") }, in: { $cond: [ { $gt: ["$$this.date", "$$value.date"] }, "$$this", "$$value" ] } } } } }, // 第三步:判断最大date元素的b/a比值是否≥2 { $match: { $expr: { $gte: [ { $divide: ["$latestValue.b", "$latestValue.a"] }, 2 ] } } }, // 可选:移除临时添加的latestValue字段,返回原始文档结构 { $project: { latestValue: 0 } } ])
代码解释
- $match(第一步):直接过滤出
counter字段值小于201的文档,先缩小处理范围,提升查询效率。 - $addFields + $reduce:通过
$reduce遍历values数组,逐个比较元素的date字段,最终保留date最大的元素,存入临时字段latestValue。 - $match(第三步):借助
$expr在查询中使用聚合表达式,计算latestValue.b与latestValue.a的比值,判断是否大于等于2,留下符合条件的文档。 - $project(可选):如果不需要临时字段
latestValue,可以用这一步移除它,返回和原始结构一致的文档。
注意事项
如果values数组中存在a为0的元素,$divide会触发报错。若有这种场景,需要在第三步的$match中额外添加$ne: ["$latestValue.a", 0]的过滤条件。
内容的提问来源于stack exchange,提问作者Gandalf
相关产品推荐
相关产品推荐

