如何在MongoDB中按日期筛选文档并提取数组内指定子文档?
MongoDB 筛选指定日期文档中数组内的目标子文档
你的原查询能匹配到对应日期的文档,但无法过滤prices数组内的子文档,原因是$elemMatch仅用于判断文档是否包含符合条件的数组元素,不会修改返回的数组内容。要单独提取符合条件的子文档,需要使用聚合管道来处理,以下是两种可行方案:
方案一:展开数组后筛选(推荐,逻辑直观)
通过$unwind展开数组,将每个子文档转为独立文档,再筛选目标内容,最后提取子文档作为根文档:
db.collection.aggregate([ // 第一步:匹配指定日期的文档 { $match: { date: ISODate("2021-08-02T00:00:00.000+00:00") } }, // 第二步:展开prices数组,每个子文档成为独立的文档 { $unwind: "$prices" }, // 第三步:筛选inventoryCode为USSW的子文档 { $match: { "prices.inventoryCode": "USSW" } }, // 第四步:将子文档作为返回结果的根文档 { $replaceRoot: { newRoot: "$prices" } } ])
执行后会直接返回你期望的结果:
{"_id": {"$oid": "ddks12"}, "inventoryCode": "USSW", "price": 102}
方案二:用$filter过滤数组后提取
如果不想先展开数组,可以先用$filter在投影阶段筛选数组内的目标元素,再展开并提取:
db.collection.aggregate([ // 匹配指定日期且包含目标子文档的文档 { $match: { date: ISODate("2021-08-02T00:00:00.000+00:00"), "prices.inventoryCode": "USSW" } }, // 过滤prices数组,只保留inventoryCode为USSW的元素 { $project: { prices: { $filter: { input: "$prices", cond: { $eq: ["$$this.inventoryCode", "USSW"] } } }, _id: 0 } }, // 展开过滤后的数组 { $unwind: "$prices" }, // 将子文档作为根文档返回 { $replaceRoot: { newRoot: "$prices" } } ])
关键说明
普通查询(如你原有的$and+$elemMatch)仅用于筛选文档,不会对文档内的数组元素进行过滤。要实现数组元素的提取,必须借助聚合管道的数组处理操作($unwind、$filter等)来完成数据的转换和筛选。
内容的提问来源于stack exchange,提问作者JamesHudson81
相关产品推荐
相关产品推荐

