Mongodb 排序内部数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15388127/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mongodb sort inner array
提问by Ricky Hartmann
I've been looking for a while now and can't seem to sort an inner array and keep that in the doc that I'm currently working with.
我一直在寻找一段时间,似乎无法对内部数组进行排序并将其保存在我目前正在使用的文档中。
{
"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")
}
]
}
}
}
So I want to keep the item to be returned as the service, but have my updates array sorted. So far with the shell I have:
所以我想保留作为服务返回的项目,但对我的更新数组进行排序。到目前为止,我拥有的外壳:
db.servers.aggregate(
{$unwind:'$service'},
{$project:{'service.apps':1}},
{$unwind:'$service.apps'},
{$project: {'service.apps.updates':1}},
{$sort:{'service.apps.updates.date':1}});
Anyone think they can help on this?
有人认为他们可以帮助解决这个问题吗?
回答by JohnnyHK
You can do this by $unwind
ing the updates
array, sorting the resulting docs by date
, and then $group
ing them back together on _id
using the sorted order.
您可以通过$unwind
ingupdates
数组,按 对结果文档进行排序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'}})
回答by Xavier Guihot
Starting in Mongo 4.4
, the $function
aggregation operator allows applying a custom javascript function to implement behaviour not supported by the MongoDB Query Language.
从 开始Mongo 4.4
,$function
聚合运算符允许应用自定义 javascript 函数来实现 MongoDB 查询语言不支持的行为。
For instance, in order to sort an array of objects by one of their fields:
例如,为了按对象的一个字段对对象数组进行排序:
// {
// "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") }
// ]}}
// }
This modifies the array in place, without having to apply a combination of expensive $unwind
, $sort
and $group
stages.
这会就地修改数组,而不必应用昂贵的$unwind
,$sort
和$group
阶段的组合。
$function
takes 3 parameters:
$function
需要3个参数:
body
, which is the function to apply, whose parameter is the array to modify.args
, which contains the fields from the record that thebody
function takes as parameter. In our case"$service.apps.updates"
.lang
, which is the language in which thebody
function is written. Onlyjs
is currently available.
body
,这是要应用的函数,其参数是要修改的数组。args
,其中包含该body
函数作为参数的记录字段。在我们的情况下"$service.apps.updates"
。lang
,这body
是编写函数的语言。仅js
当前可用。