Mongoose嵌套数组全元素匹配查询条件调整问题
解决MongoDB筛选所有子文档字段均满足条件的问题
嘿,我完全懂你的痛点——你想要找出那些items数组里每一个对象的totalPrice都小于100的文档,但当前的查询只会返回至少有一个符合条件元素的文档,连包含totalPrice:120的文档都能混进来,这肯定不是你要的结果。
为什么原来的查询不行?
你用的{"items.totalPrice": { $lt: 100 }}其实是在告诉MongoDB:“给我所有存在至少一个items元素满足totalPrice<100的文档”,它不会去检查数组里的其他元素。
正确的查询方式
这里有两种靠谱的解决方案,你可以根据自己的MongoDB版本和习惯选择:
方法一:用$not + $elemMatch(兼容所有版本)
我们换个思路——排除掉那些存在任何一个totalPrice≥100的items元素的文档,剩下的就是所有items都满足totalPrice<100的文档。
代码示例:
MyObjModel.find({ $not: { items: { $elemMatch: { totalPrice: { $gte: 100 } } } } })
或者更简洁的写法(效果完全一致):
MyObjModel.find({ "items.totalPrice": { $not: { $gte: 100 } } })
方法二:用$expr + $allElementsTrue(MongoDB 3.2+适用)
如果你想用更直观的方式直接检查数组里的所有元素,可以用表达式查询:
MyObjModel.find({ $expr: { $allElementsTrue: { $map: { input: "$items", as: "item", in: { $lt: ["$$item.totalPrice", 100] } } } } })
这个逻辑很清晰:$map把每个items元素转换成一个布尔值(判断totalPrice是否小于100),然后$allElementsTrue验证这个布尔数组里的所有值都是true——也就是所有元素都符合条件。
额外:排除空数组的情况
如果你的文档里可能存在空的items数组,而你不想把这些文档包含进来,可以在查询里加上items: { $ne: [] }的条件,比如:
MyObjModel.find({ $not: { items: { $elemMatch: { totalPrice: { $gte: 100 } } } }, items: { $ne: [] } })
内容的提问来源于stack exchange,提问作者phoebus
相关产品推荐
相关产品推荐

