首页 > 解决方案 > 在MongoDB中按desc从每个数组顺序中选择前n个项目

问题描述

考虑具有以下文件的收集学校:

{
    "_id" : 1,
    "name" : "Class 1",
    "students" : [  
        { "rollNo" : 10001, "name" : "Ram", "score" : 65 },
        { "rollNo" : 10002, "name" : "Shyam", "score" : 90 },
        { "rollNo" : 10003, "name" : "Mohan", "score" : 75 }       
        ]
},
{
    "_id" : 2,
    "name" : "Class 2",
    "students" : [  
        { "rollNo" : 20001, "name" : "Krishna", "score" : 88 },
        { "rollNo" : 20002, "name" : "Sohan", "score" : 91 },
        { "rollNo" : 20003, "name" : "Radhika", "score" : 82 },
        { "rollNo" : 20004, "name" : "Komal", "score" : 55 },
        { "rollNo" : 20005, "name" : "Sonam", "score" : 91 }            
        ]
},
{
    "_id" : 3,
    "name" : "Class 3",
    "students" : [  
        { "rollNo" : 30001, "name" : "Monika", "score" : 77 },      
        { "rollNo" : 30002, "name" : "Rahul", "score" : 81 }                
        ]
}

在这里,我的目标是让每个数组中的前 N ​​名学生按分数降序排列(考虑前 2 名学生按分数排序)。我的预期结果是:

在此处输入图像描述

标签: mongodbmongoose

解决方案


如果您只想要没有分组的学生记录,您可以简单地$unwind然后$sort

db.collection.aggregate([
  { $unwind: "$students" },
  { $sort: { "students.score": -1 } },
  { $limit: 2 }
])

然而,这将留下students对象。为了获得更清晰的输出,您可以$replaceRoot使用$mergeObjects

db.collection.aggregate([
  { $unwind: "$students" },
  { $sort: { "students.score": -1 } },
  { $replaceRoot: {
      newRoot: {
        $mergeObjects: [ { _id: "$_id", class: "$name" }, "$students" ]
      }
    }
  },
  { $limit: 2 }
])

看到它在这里工作

这将为您提供以下输出:

[
  {
    "_id": 2,
    "class": "Class 2",
    "name": "Sonam",
    "rollNo": 20005,
    "score": 91
  },
  {
    "_id": 2,
    "class": "Class 2",
    "name": "Sohan",
    "rollNo": 20002,
    "score": 91
  }
]

更新

使用它来获得每个组的前 2 名:

db.collection.aggregate([
  { $unwind: "$students" },
  { $sort: { "students.score": -1 }
  },
  {
    $group: {
      "_id": "$_id",
      "name": { $first: "$name" },
      "students": { $push: "$students" }
    }
  },
  {
    "$project": {
      "top_two": { "$slice": [ "$students", 2 ] }
    }
  }
])

看到它在这里工作


推荐阅读