如何在MongoDB中查询数组内满足指定条件的多个元素
解决方案
$elemMatch在投影阶段仅会返回数组中第一个匹配条件的元素,要获取全部匹配项,需使用MongoDB聚合框架实现,以下是两种常用方案:
方案1:使用$filter操作符(推荐)
该方案最高效简洁,无需拆分数组即可直接过滤得到所有符合条件的元素:
db.yourCollectionName.aggregate([ // 可选:先过滤出至少包含一个符合条件元素的文档,减少后续计算量 { $match: { "someArray.Date": { $lte: "2020-12-31" } } }, // 过滤数组,保留所有符合条件的元素 { $addFields: { // 如果需要保留原数组,可将字段名改为自定义名称如filteredArray someArray: { $filter: { input: "$someArray", cond: { $lte: [ "$$this.Date", "2020-12-31" ] } } } } } ])
参数说明:
input:指定要处理的目标数组cond:定义过滤规则,$$this指代数组当前遍历的元素
方案2:使用$unwind + $match + $group组合
如果需要对匹配到的元素做更复杂的后续处理(如字段修改、关联查询等),可以使用该方案:
db.yourCollectionName.aggregate([ { $match: { "someArray.Date": { $lte: "2020-12-31" } } }, // 将数组拆分为单个元素的独立文档 { $unwind: "$someArray" }, // 筛选符合条件的元素文档 { $match: { "someArray.Date": { $lte: "2020-12-31" } } }, // 按原文档ID分组,重新组装符合条件的数组 { $group: { _id: "$_id", // 需要保留原文档的其他字段可以在此处添加,如:name: {$first: "$name"} someArray: { $push: "$someArray" } } } ])
注意事项
如果数组中的Date字段存储的是ISODate类型而非字符串,只需将查询条件中的"2020-12-31"替换为ISODate("2020-12-31T00:00:00Z")即可。
内容的提问来源于stack exchange,提问作者sorohimm
相关产品推荐
相关产品推荐

