如何匹配MongoDB数组中子文档满足字段比较条件的文档?
匹配包含满足字段比较条件的子文档数组的MongoDB文档
要匹配属性A为嵌入式文档数组,且数组中至少存在一个子文档满足subDocument.propertyX < subDocument.propertyY的文档,你原来的写法无法生效——原因是**$elemMatch中的常规查询操作符(如$lt)不支持引用同一子文档的其他字段**,只能和常量值对比。
正确实现方式(MongoDB 3.6+)
方法一:使用$expr直接查询
通过$expr结合聚合表达式,实现字段间的比较并判断数组中是否存在符合条件的元素:
db.collection.find({ $expr: { $anyElementTrue: { $map: { input: "$A", as: "subDoc", in: { $lt: ["$$subDoc.propertyX", "$$subDoc.propertyY"] } } } } })
$map遍历数组A的每个子文档,生成一个布尔值数组,每个值对应子文档是否满足propertyX < propertyY$anyElementTrue检查布尔数组中是否存在至少一个true,以此判断是否有符合条件的子文档
方法二:通过$filter判断数组长度
另一种思路是过滤出符合条件的子文档,再判断过滤后的数组长度是否大于0:
db.collection.find({ $expr: { $gt: [ { $size: { $filter: { input: "$A", cond: { $lt: ["$$this.propertyX", "$$this.propertyY"] } } } }, 0 ] } })
$filter从数组A中筛选出满足条件的子文档$size获取筛选后数组的长度,$gt: [..., 0]表示长度大于0,即存在符合条件的子文档
方法三:聚合管道中使用$match
如果需要后续执行其他聚合操作,可将上述逻辑放在聚合管道的$match阶段:
db.collection.aggregate([ { $match: { $expr: { $anyElementTrue: { $map: { input: "$A", as: "subDoc", in: { $lt: ["$$subDoc.propertyX", "$$subDoc.propertyY"] } } } } } } // 后续可添加其他聚合阶段 ])
内容的提问来源于stack exchange,提问作者Viriato
相关产品推荐
相关产品推荐

