Ric*_*ann 24 mongodb aggregation-framework
我一直在寻找一段时间,似乎无法对内部数组进行排序,并将其保留在我正在使用的文档中.
{
"service": {
"apps": {
"updates": [
{
"n" : 1
"date": ISODate("2012-03-10T16:15:00Z")
},
{
"n" : 2
"date": ISODate("2012-01-10T16:15:00Z")
},
{
"n" : 5
"date": ISODate("2012-07-10T16:15:00Z")
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以我想保持项目作为服务返回,但我的更新数组已排序.到目前为止,我有shell:
db.servers.aggregate(
{$unwind:'$service'},
{$project:{'service.apps':1}},
{$unwind:'$service.apps'},
{$project: {'service.apps.updates':1}},
{$sort:{'service.apps.updates.date':1}});
Run Code Online (Sandbox Code Playgroud)
有人认为他们可以提供帮助吗?
Joh*_*yHK 47
您可以通过$unwind对updates数组执行此操作,对生成的文档进行排序date,然后使用排序顺序将$group它们重新组合在一起_id.
db.servers.aggregate(
{$unwind: '$service.apps.updates'},
{$sort: {'service.apps.updates.date': 1}},
{$group: {_id: '$_id', 'updates': {$push: '$service.apps.updates'}}},
{$project: {'service.apps.updates': '$updates'}})
Run Code Online (Sandbox Code Playgroud)
Xav*_*hot 13
从 开始Mongo 4.4,$function聚合运算符允许应用自定义 javascript 函数来实现 MongoDB 查询语言不支持的行为。
例如,为了按对象的一个字段对对象数组进行排序:
// {
// "service" : { "apps" : { "updates" : [
// { "n" : 1, "date" : ISODate("2012-03-10T16:15:00Z") },
// { "n" : 2, "date" : ISODate("2012-01-10T16:15:00Z") },
// { "n" : 5, "date" : ISODate("2012-07-10T16:15:00Z") }
// ]}}
// }
db.collection.aggregate(
{ $set: {
{ "service.apps.updates":
{ $function: {
body: function(updates) {
updates.sort((a, b) => a.date - b.date);
return updates;
},
args: ["$service.apps.updates"],
lang: "js"
}}
}
}
)
// {
// "service" : { "apps" : { "updates" : [
// { "n" : 2, "date" : ISODate("2012-01-10T16:15:00Z") },
// { "n" : 1, "date" : ISODate("2012-03-10T16:15:00Z") },
// { "n" : 5, "date" : ISODate("2012-07-10T16:15:00Z") }
// ]}}
// }
Run Code Online (Sandbox Code Playgroud)
这会就地修改数组,而不必应用昂贵的$unwind,$sort和$group阶段的组合。
$function 需要3个参数:
body,这是要应用的函数,其参数是要修改的数组。args,其中包含该body函数作为参数的记录字段。在我们的情况下"$service.apps.updates"。lang,这body是编写函数的语言。仅js当前可用。Xav*_*hot 12
从 开始Mongo 5.2,这就是新$sortArray聚合运算符的确切用例:
// {
// service: { apps: { updates: [
// { n: 1, date: ISODate("2012-03-10") },
// { n: 2, date: ISODate("2012-01-10") },
// { n: 5, date: ISODate("2012-07-10") }
// ]}}
// }
db.collection.aggregate([
{ $set: {
"service.apps.updates": {
$sortArray: {
input: "$service.apps.updates",
sortBy: { date: 1 }
}
}
}}
])
// {
// service: { apps: { updates: [
// { n: 2, date: ISODate("2012-01-10") },
// { n: 1, date: ISODate("2012-03-10") },
// { n: 5, date: ISODate("2012-07-10") }
// ]}}
// }
Run Code Online (Sandbox Code Playgroud)
这:
$sortArray) 进行排序service.apps.updates(input: "$service.apps.updates")dates (sortBy: { date: 1 })$unwind,$sort和$group阶段的组合