MongoDB按平均组合数或嵌套子数组排序

dee*_*juk 6 php arrays mongodb

有一些问题在MongoDB中找到最好的方法,可以说它是一个关系数据集,所以我可能会被定为.看看它是否有可能仍然是一个挑战.

我目前需要通过物流经理在其所在部门的货车上的每日平均里程数进行订购,并且还需要在单独的每周平均值的单独列表中订购.

数据库中的First先生设置如下

{
   "_id" : ObjectId("555cf04fa3ed8cc2347b23d7"),
   "name" : "My Manager 1",
   "vans" : [ 
       {
           "name" : "van1",
           "miles" : NumberLong(56)
       },
       {
           "name" : "van2",
           "miles" : NumberLong(34)
       }
   ]
}
Run Code Online (Sandbox Code Playgroud)

但我不知道如何在不知道父数组键的情况下通过嵌套数组值进行排序(这些将是标准的0-x)

所以我的下一个选择是废弃这个想法,只是在第一个集合中有名称,第二个集合中的vans与经理的Id.

所以从上面的例子中移除面包车并添加这个集合(面包车)

{
   "_id" : ObjectId("555cf04fa3ed8cc2347b23d9"),
   "name" : "van1",
   "miles" : NumberLong(56),
   "manager_id" : "555cf04fa3ed8cc2347b23d7"
}
Run Code Online (Sandbox Code Playgroud)

但是因为我需要通过经理显示结果,我如何在查询中(如果可能)订购此集合中的平均里程数,其中id = x,然后按其ID显示经理.

谢谢你的帮助

bag*_*rat 2

如果sManager的数量有限Van,那么您的第一种方法更好,因为您不必对数据库进行两次单独的调用/查询来收集您的信息。

那么问题来了,如何计算平均里程Manager,这Aggregation Framework会对你有很大帮助。这是一个可以获取所需数据的查询:

db.manager.aggregate([
                        {$unwind: "$vans"},
                        {$group:
                                  {_id: 
                                         {
                                            _id: "$_id", 
                                            name: "$name"
                                         }, 
                                   avg_milage: {$avg: "$vans.miles"}
                                  }
                        },
                        {$sort: {"avg_milage": -1}},
                        {$project: 
                                    {_id: "$_id._id", 
                                     name: "$_id.name", 
                                     avg_milage: "$avg_milage"
                                    }
                        }
                    ])
Run Code Online (Sandbox Code Playgroud)

第一步$unwind只是解开vans数组,并为数组的每个元素创建一个单独的文档。

然后$group阶段获取具有相同(_id, name)对的所有文档,并在字段中计算这些文档中字段avg_milage的平均值。miles

该阶段很明显,它只是使用新字段作为排序键$sort按降序对文档进行排序。avg_milage

最后,最后$project一步只是通过进行适当的投影来清理文档,只是为了美观:)

您的第二个期望结果需要类似的东西:

db.manager.aggregate([
                        {$unwind: "$vans"},
                        {$group:
                                  {_id: 
                                         {
                                            _id: "$_id", 
                                            name: "$name"
                                         }, 
                                   total_milage: {$sum: "$vans.miles"}
                                  }
                        },
                        {$sort: {"total_milage": -1}},
                        {$project: 
                                    {_id: "$_id._id", 
                                     name: "$_id.name", 
                                     weekly_milage: {
                                                       $multiply: [
                                                                     "$total_milage", 
                                                                     7
                                                                  ]
                                                    }

                                    }
                        }
                    ])
Run Code Online (Sandbox Code Playgroud)

这将产生每周行驶里程的列表Managers,按降序排列。这样您就可以得到$limit结果,Manager例如获得最高里程的结果。

以非常相似的方式,您可以获取货车的信息:

db.manager.aggregate([
                        {$unwind: "$vans"},
                        {$group:
                                  {_id: "$vans.name", 
                                   total_milage: {$sum: "$vans.miles"}
                                  }
                        },
                        {$sort: {"total_milage": -1}},
                        {$project: 
                                    {van_name: "$_id", 
                                     weekly_milage: {
                                                       $multiply: [
                                                                     "$total_milage", 
                                                                     7
                                                                  ]
                                                    }

                                    }
                        }
                    ])
Run Code Online (Sandbox Code Playgroud)