node.js - toObjectId 用于查找和聚合的字符串数组

标签 node.js mongodb mongoose aggregation-framework

我有 2 个模型,一个是团体模型,另一个是学生模型。组看起来像这样

{
    "_id" : ObjectId("5c8d28ef7e0e542854b7b904"),
    "name" : "Homeroom ",
    "year" : 2019,
    "schoolID" : ObjectId("5c1a735fc98da061141475a1"),
    "teachers" : [ 
        {
            "_id" : "5c1a7677c98da061141475aa",
            "firstName" : "Ayam"
        }, 
        {
            "_id" : "5c1a7677c98da061141475a9",
            "firstName" : "Itik"
        }
    ],
    "addedOn" : ISODate("2019-03-16T16:48:47.372Z"),
    "lastModified" : ISODate("2019-03-16T16:48:47.372Z"),
    "__v" : 0,
    "status" : 1,
    "students" : [ 
        "5c1a79f7c98da061141475b7", 
        "5c3bfea37774fb0b55000cb5", 
        "5c1a7c69c98da061141475bb", 
        "5c3bfea37774fb0b55000cb4", 
        "5c1a7d32c98da061141475be", 
        "5c3bfea37774fb0b55000cb7"
    ]
}

所在字段students上面将学生的 _id(字符串格式)存储在 Students 模型中。

现在我尝试使用聚合进行查找,我想出了这样的结果:

Group.aggregate([
            { $match: { _id: mongoose.mongo.ObjectId(groupID) } },
            { $lookup: { 
              from: "Students", localField: "students", foreignField: "_id", as: "studentList"  
            } },
              { $unwind: "$studentList" },
              { $replaceRoot: { newRoot: "$students" } }
          ], function(err, result){
            if (err){
              console.log("imin err 102: " )
              console.log(err)
            }else{
              console.log("imini 105 result")
              console.log(result);
            }
          });

现在我明白上面的代码不会产生任何结果,因为 students Model Group 内部存储为 String,而模型 Student 内部的 _id 是一个 ObjectId。 Mongodb现在有$toObjectId但由于我的模型包含一个字符串数组,我不知道如何实现 $toObjectId正确。

这是供学生使用的示例文档

{
    "_id" : ObjectId("5c1a79f7c98da061141475b7"),
    "firstName" : "Ibrahim",
    "kelasID" : ObjectId("5c429f9906f2a805bc6cd494"),
    "lastName" : "Ali",
    "schoolID" : ObjectId("5c1a735fc98da061141475a1"),
    "year" : 2018,
    "__v" : 0,
    "addedOn" : ISODate("2018-12-25T04:27:47.909Z"),
    "checkIn" : false,
    "checkInStatus" : 1,
    "contactNo1" : "012225656",
    "father" : "Ali",
    "fatherID" : "8852245",
    "idType" : 0,
    "lastModified" : ISODate("2018-12-25T04:27:47.909Z"),
    "mother" : "",
    "motherID" : ""
}
{
    "_id" : ObjectId("5c3bfea37774fb0b55000cb5"),
    "idType" : 0,
    "checkIn" : false,
    "checkInStatus" : 1,
    "year" : 2019,
    "schoolID" : ObjectId("5c1a735fc98da061141475a1"),
    "kelasID" : ObjectId("5c1a7534c98da061141475a3"),
    "firstName" : "Umar",
    "lastName" : "Bin Al-Khattab",
    "contactNo1" : "601222",
    "status" : 1,
    "addedOn" : ISODate("2019-01-14T03:14:43.597Z"),
    "lastModified" : ISODate("2019-01-14T03:14:43.597Z"),
    "__v" : 0
}
{
    "_id" : ObjectId("5c1a7c69c98da061141475bb"),
    "idType" : 0,
    "checkIn" : false,
    "checkInStatus" : 1,
    "year" : 2018,
    "schoolID" : ObjectId("5c1a735fc98da061141475a1"),
    "kelasID" : ObjectId("5c1a7540c98da061141475a5"),
    "firstName" : "Abdul Rahman",
    "lastName" : "Affan",
    "father" : "Affan",
    "fatherID" : "54321",
    "contactNo1" : "602288",
    "status" : 1,
    "addedOn" : ISODate("2018-12-25T04:30:16.130Z"),
    "lastModified" : ISODate("2018-12-25T04:30:16.130Z"),
    "__v" : 0
}

最佳答案

你必须$mapstudents 字段上将 String id 转换为 ObjectId

Group.aggregate(
  [
    { "$match": { "_id": mongoose.mongo.ObjectId(groupID) } },
    { "$addFields": {
      "students": {
        "$map": {
          "input": "$students",
          "in": { "$toObjectId": "$$this" }
        }
      }
    }},
    {
      "$lookup": {
        "from": "Students",
        "localField": "students",
        "foreignField": "_id",
        "as": "studentList"
      }
    },
    { "$unwind": "$studentList" },
    { "$replaceRoot": { "newRoot": "$students" } }
  ],
  function(err, result) {
    if (err) {
      console.log("imin err 102: ");
      console.log(err);
    } else {
      console.log("imini 105 result");
      console.log(result);
    }
  }
)

关于node.js - toObjectId 用于查找和聚合的字符串数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55404207/

相关文章:

node.js - Mongoose 仅在更改时更新值

javascript - 从 Node 中的多个嵌套回调中返回值

javascript - Node.js 和 Backbone.js 的集成

macos - Mac 的 MongoHub mongo 数据库 GUI 不再有效

javascript - 如何在 Express.js 和 mongoose 中编写异步 for-each 循环?

node.js - 如何为 GridFS 集合创建 Mongoose 模型?

node.js - 设置缩略图内容类型

javascript - 在大文件的 http 传输中间歇性获取 TCP._onclose

mongodb - MGO TTL 索引创建以选择性地删除文档

mongodb - 了解性能 : mongo aggregation vs count