如何用猫鼬对填充的二级深子文档数组进行排序

时间:2019-03-25 11:40:01

标签: mongodb mongoose schema populate

我正在用猫鼬和nodejs开发一个api。

基本上有一个课程模型,一个学生模型和一个小组模型。对于每门课程,课程文档中都有两个字段:

。字段“学生”:引用学生模型的objectid数组。

。字段“组”:子文档的数组,每个子文档都有一个引用“组模型”的“ groupId”字段和一个“学生”字段:一个引用学生模型的objectid数组。这些是按课程入组的学生。

我可以按课程获取排序后的学生名单,但无法按组获取此名单。我可以使列表未排序,但无法排序。

这些是我的主要模式:

组模型->组集合:

const groupSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    unique: true
  }
})

学生模型->学生收藏:

const studentSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    index:true
  },
  firstName: {
    type: String,
    required: true,
    index:true
  },
  lastName: {
    type: String,
    required: true,
    index:true
  }
})

课程模型->课程集合:

const courseSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    index: true
  },
  students: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Student'
    }
  ],
  groups: [
    {
      groupId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Group'
      },
      students: [
        {
          type: mongoose.Schema.Types.ObjectId,
          ref: 'Student'    
        }
      ],
    }
  ]
})

使用下一个查询,我可以按课程获得按字母顺序排序的学生列表,即使我可以使用“ where”进行过滤也没有问题:

const query = await Course.findById(courseId)
    .select('students')
    .populate({
      path: 'students',
      select: ['_id', 'firstName', 'lastName', 'name'],
      match: where,
      options: {
        sort: {
          firstName: 1,
          lastName: 1,
          name: 1
        }
      }
    })

该查询很好,但是我希望另一个查询按组和课程返回排序的学生列表。我正在使用类似的查询,但是具有嵌套的子文档数组:

  const query = await Course.findById(courseId)
    .where('groups.groupId').equals(groupId)
    .select('groups.$.students')
    .populate({
      path: 'groups.students',
      select: ['_id', 'firstName', 'lastName', 'name'],
      match: where,
      // options: {
      //   sort: {
      //     firstName: 1,
      //     lastName: 1,
      //     name: 1
      //   }
      // }
    })

通过这种方式,我获得了学生名单,但未排序。如果取消注释对填充列表进行排序的选项,则会收到错误消息:

“由于路径组是文档数组的子属性,因此无法在路径组.students上填充sort”。

在使用sql数据库之前,我是mongodb的新手,但是我正在学习使用mongoose的mongodb。我不知道我的架构设计是否能最好地实现我想要的。

由于这不起作用,为了解决此问题,我将“ sort”方法应用于查询进行排序,如下所示:

  query.groups[0].students.sort((st1, st2) => {
    if (st1.firstName > st2.firstName) return 1
    if (st1.lastName > st2.lastName) return 1
    if (st1.name > st2.name) return 1
    return -1
  })

有没有一种方法可以使用查询和/或填充方法?

按照有关mongodb聚合框架的专家建议,我找到了解决问题的第一种方法。我使用的汇总:

db.courses.aggregate([
    { $match: { _id: ObjectId("5c6d43c98068bc0836a62b65") }},
    { $project: {
        _id: 0,
        groups: '$groups'
        }
    },
    { $unwind: "$groups" },
    { $match: { 'groups.groupId': ObjectId("5c94b0d81ce16357d74549dd") }},
    { $project: {
        students: '$groups.students'
    }},
    { $unwind: '$students' },
    { $lookup: {
        from: "students",
        localField: "students",
        foreignField: "_id",
        as: "students"
    }},
    { $project: {
        id: { $arrayElemAt: [ "$students._id", 0 ] },
        nie: { $arrayElemAt: [ "$students.nie", 0 ] },
        name: { $arrayElemAt: [ "$students.name", 0 ] },
        firstName: { $arrayElemAt: [ "$students.firstName", 0 ] },
        lastName: { $arrayElemAt: [ "$students.lastName", 0 ] }
    }},
    { $sort: { firstName: 1, lastName: 1, name: 1 } }
])

0 个答案:

没有答案