MongoDB 如何获取delivery数组内指定状态对应元素的createdAt值
从MongoDB嵌套数组中提取指定状态对应日期值的实现方法
你贴的文档片段里的"createdAt": "$date": "2020-12-21T03:50:33.877Z"属于复制时的格式残缺——MongoDB导出/打印BSON日期类型时,实际结构会是"createdAt": {"$date": "2020-12-21T03:50:33.877Z"},也就是$date是createdAt字段值的内部结构,不是和createdAt平级的键。实际查询取值时直接取item.createdAt就能拿到正确的日期值,不需要额外拆解内部的$date层级。
下面分别给出两种常用场景下的实现方式,完全匹配你要的取值效果:
1. 直接在数据库端查询取值(聚合查询)
不需要把整段数组拉取到本地,用MongoDB内置的聚合运算符就能直接筛选出对应元素的createdAt值:
db.你的集合名.aggregate([ // 先匹配到你要查询的目标文档,替换成你自己的文档过滤条件 { $match: { name: "Roboert Browning" } }, { $project: { // 筛选delivery数组中状态为Not Started的元素,取第一个匹配项 notStartedCreatedAt: { $first: { $filter: { input: "$delivery", as: "deliver", cond: { $eq: ["$$deliver.status", "Not Started"] } } } }, // 筛选delivery数组中状态为Accepted的元素,取第一个匹配项 acceptedCreatedAt: { $first: { $filter: { input: "$delivery", as: "deliver", cond: { $eq: ["$$deliver.status", "Accepted"] } } } } }}, // 从筛选后的子对象中取出最终的createdAt值 { $project: { notStartedCreatedAt: "$notStartedCreatedAt.createdAt", acceptedCreatedAt: "$acceptedCreatedAt.createdAt", _id: 0 }} ])
执行后会直接返回结果:
{ "notStartedCreatedAt": "2020-12-21T03:50:33.877Z", "acceptedCreatedAt": "2020-12-21T03:51:20.915Z" }
和你给出的示例输出完全一致。
2. 本地获取文档后直接取值
如果已经把整条文档从数据库查询到本地的JS运行环境里,不需要写复杂的聚合逻辑,用数组原生方法就能快速取值:
// 假设doc是从数据库查到的完整文档对象 // 取Not Started状态对应的createdAt const notStartedCreatedAt = doc.delivery.find(item => item.status === "Not Started")?.createdAt; // 取Accepted状态对应的createdAt const acceptedCreatedAt = doc.delivery.find(item => item.status === "Accepted")?.createdAt;
最终得到的两个值就是你需要的两个时间字符串:
notStartedCreatedAt:2020-12-21T03:50:33.877Z(对应Not Started状态条目)acceptedCreatedAt:2020-12-21T03:51:20.915Z(对应Accepted状态条目)
注意:如果文档中存在同一状态对应多个delivery条目,上面的
$first和find方法都会取第一个匹配到的元素,如果需要取最后一个匹配的元素,可以把聚合里的$first换成$last,本地JS逻辑换成doc.delivery.filter(item => item.status === "xxx").pop()即可。
内容的提问来源于stack exchange,提问作者Pinky Promise
相关产品推荐
相关产品推荐

