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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 13:06:51  来源:igfitidea点击:

Mongodb sort inner array

mongodbaggregation-framework

提问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 $unwinding the updatesarray, sorting the resulting docs by date, and then $grouping them back together on _idusing the sorted order.

您可以通过$unwindingupdates数组,按 对结果文档进行排序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 $functionaggregation 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, $sortand $groupstages.

这会就地修改数组,而不必应用昂贵的$unwind,$sort$group阶段的组合。

$functiontakes 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 the bodyfunction takes as parameter. In our case "$service.apps.updates".
  • lang, which is the language in which the bodyfunction is written. Only jsis currently available.
  • body,这是要应用的函数,其参数是要修改的数组。
  • args,其中包含该body函数作为参数的记录字段。在我们的情况下"$service.apps.updates"
  • lang,这body是编写函数的语言。仅js当前可用。