如何在Node.js中查询MongoDB集合里history数组最新状态为running的文档
Node.js中MongoDB查询:筛选history数组最新条目state为'running'的文档
要实现你需要的查询(找出history数组中按createdAt排序后的最新条目state为'running'的文档),Node.js里可以通过聚合管道或MongoDB 5.2+的表达式查询两种方式实现,以下是具体方案:
方案一:聚合管道(兼容所有MongoDB版本)
如果你的MongoDB版本低于5.2(无$sortArray运算符),可以用$unwind+$sort+$group的组合定位每个文档的最新history条目:
// 原生MongoDB驱动示例 const { MongoClient } = require('mongodb'); async function getRunningDocs() { const client = await MongoClient.connect('your-mongodb-uri'); const db = client.db('your-db-name'); const result = await db.collection('your-collection').aggregate([ // 拆分history数组为独立文档 { $unwind: '$history' }, // 按文档ID分组,同时按createdAt降序排序(确保最新条目排在最前) { $sort: { _id: 1, 'history.createdAt': -1 } }, // 重新组合文档,保留原字段,并提取最新的history条目 { $group: { _id: '$_id', name: { $first: '$name' }, history: { $push: '$history' }, // 保留完整的history数组 latestHistory: { $first: '$history' } // 存储最新的history条目 } }, // 筛选最新条目state为'running'的文档 { $match: { 'latestHistory.state': 'running' } }, // 可选:移除临时字段latestHistory,恢复原文档结构 { $project: { latestHistory: 0 } } ]).toArray(); await client.close(); return result; }
如果你的MongoDB版本在5.2及以上,可用$sortArray简化聚合逻辑:
async function getRunningDocs() { const client = await MongoClient.connect('your-mongodb-uri'); const db = client.db('your-db-name'); const result = await db.collection('your-collection').aggregate([ // 添加临时字段:按createdAt降序排序后的history数组 { $addFields: { sortedHistory: { $sortArray: { input: '$history', sortBy: { createdAt: -1 } } } } }, // 筛选排序后数组第一个元素(最新条目)state为'running'的文档 { $match: { 'sortedHistory.0.state': 'running' } }, // 移除临时字段 { $project: { sortedHistory: 0 } } ]).toArray(); await client.close(); return result; }
方案二:表达式查询(MongoDB 5.2+ 简洁版)
利用$expr结合$sortArray和$first,直接在find查询中完成筛选,无需聚合管道:
async function getRunningDocs() { const client = await MongoClient.connect('your-mongodb-uri'); const db = client.db('your-db-name'); // 逻辑:将history按createdAt降序排序后取第一个元素,判断其state是否为'running' const result = await db.collection('your-collection').find({ $expr: { $eq: [ { $first: { $sortArray: { input: '$history', sortBy: { createdAt: -1 } } } }.state, 'running' ] } }).toArray(); await client.close(); return result; }
逻辑说明
你的C#代码中w.history.OrderBy(o => o.createdAt).Last().status == "running"的逻辑,对应MongoDB里就是:
- 将
history数组按createdAt升序排序后取最后一个元素,或 - 按
createdAt降序排序后取第一个元素
两种方式等价,都能定位到时间最新的条目。
验证示例文档
对于你提供的示例数据:
- 文档
_id:1的最新history条目state为'stopped',不会被返回 - 文档
_id:2的最新history条目state为'running',会被筛选出来
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

