我正在尝试找到一种查询 mongodb 集合的方法:应返回 '
state
' 的 running
值也是 'history
' 数组中的最新条目的所有文档。我可以使用 LINQ 在 C# 中使用 .Max() 和 .OrderBy() 来完成此操作,
但不能在 NodeJS 中。
没有聚合的 C#:
var filter = Filter.Where(w => w.history.OrderBy(o => o.createdAt).Last().status == "running")
以下是示例文档:
{
_id: 1,
name: 'name 1',
history: [
{
createdAt: '2024-01-01',
state: 'initialized'
},
{
createdAt: '2024-01-15',
state: 'running'
},
{
createdAt: '2024-02-02',
state: 'stopped'
}
]
},
{
_id: 2,
name: 'name 2',
history: [
{
createdAt: '2024-01-01',
state: 'initialized'
},
{
createdAt: '2024-01-20 01:15:66',
state: 'running'
},
{
createdAt: '2024-01-21 00:55:59', // this is the LATEST entry, and state=running --> return document
state: 'running'
},
{
createdAt: '2024-01-21 00:55:58',
state: 'stopped'
}
]
}
一个状态可以出现多次,因此历史数组可以包含“运行”3 次。在这种情况下,我需要返回最新的条目(使用createdAt)。它是数组中的最后一个条目并不意味着它的createdAt日期是最新日期。
尝试运行此聚合查询:
[
{
$match: {
"history.state": "running"
}
},
{
$unwind: "$history"
},
{
$match: {
"history.state": "running"
}
},
{
$sort: {
"history.createdAt": 1
}
},
{
$group: {
_id: "$_id",
name: { $first: "$name" },
mostRecentRunning: { $last: "$history" }
}
}]
这应该可以解决问题!
db.collection.aggregate([
{
$match: {
$expr: {
$eq: [
{
$getField: {
input: {
$first: {
$sortArray: {
input: "$history",
sortBy: {
createdAt: -1
}
}
}
},
field: "state"
}
},
"running"
]
}
}
}
])