【问题标题】:How to access an object within an array within a MongoDB document?如何访问 MongoDB 文档中数组中的对象?
【发布时间】:2022-01-21 19:53:36
【问题描述】:

-- 答案在底部--

我和我的项目合作伙伴正试图弄清楚如何访问数组中的对象,即我们 MongoDB 数据库中的文档中的对象。

我们正在建立一个网站,用户可以在其中创建作业(在特定课程中),创建作业后,可以导航到该课程的主页,并访问作业的页面(这将是一个通用的 .ejs 模板页面,根据我们创建的作业填写正确的信息)。

例如,在 CS 212 课程中,我们创建了作业 1(包含一些问题和答案)和作业 2。我们导航到 CS 212 的页面,单击作业 1,它应该会显示这些问题和答案。

我们想使用我们在数据库中创建的作业 ID 访问作业的数据库数据,但是,“Courses.findOne( {assignments: assignmentID} )”(类似这些内容)正在返回整个课程 ( CS 212) 对象,而不仅仅是赋值。

我们的架构如下:

const CourseSchema = new mongoose.Schema(
    {
        CourseNum: {
            type: String,
            required: true,
        },
        CourseName: {
            type: String,
            required: true,
        },
        CourseID: {
            type: String,
            required: true,
        },
        CourseCredits: {
            type: Number,
            required: true
        },
        CourseDescription: {
            type: String,
            required: true,
        },
        CourseMaterials: {
            type: String,
            required: true,
        },
        Instructors: {
            type: [String],
            required: true
        },
        Students: [String],
        assignments: [assignmentSchema]
    },
    {   timestamps: true,
        collection: 'courses' }
)

这是我们的主模型,称为 Course,在作业内部(如您在上面看到的),我们将子文档作为数组中的另一个模式传入:

const mongoose = require('mongoose');

// const assignmentSchema = require("/assignment");
const assignmentSchema = new mongoose.Schema(
    {
        assignmentId: {
            type: String,
            required: true,
            unique: true
        },
        assignmentName: {
            type: String,
            required: true,
        },
        questions: {
            type: [String],
        },
        answers: {
            type: [String],
        }
    },
    {
        timestamps: true,
        collection: 'assignments'
    }
)

如您所见,我们正在尝试根据来自课程仪表板页面的 post 方法中传入的值访问特定作业 ID,然后导航到我们的通用/动态填充作业页面,但具体来说我们的 AssignmentID 指定。

我们的代码如下:

app.get("/assignXpage/:assign", requireAuth('instructor'), function (req, res){
  let input = req.params.assign;
  // let course = req.cookies.courseid;
  console.log('input', input)
  Course.findOne({"Course.assignments": { assignmentId: input}})
    .then((result) => {
      console.log(result)
      res.render("pages/Instructor/assignmentXpage", { assign: result });
    })
    .catch((err) => {
      console.log(err);
    });
});

这段代码如下:

let input = req.params.assign;

存储我们正在查找的特定作业的 ID,但 findOne(或 find)方法无法正常工作,并返回整个 CS 212 课程。

任何帮助将不胜感激,谢谢!

-- 我们一起去的答案-- 我们使用的确切解决方案(根据下面用户的回答)是:

Course.findOne({ "assignments.assignmentId": input })
          .select({ assignments: { $elemMatch: { assignmentId: input } } })
          .then((result) => {
            res.render("pages/Student/assignmentXpagest", { assign: result });
          })
          .catch((err) => {
            console.log(err);
          });

【问题讨论】:

    标签: javascript arrays mongodb mongoose nested


    【解决方案1】:

    您可以在项目选项中使用$elematch 进行上述响应。 您的查询将与此类似。

    Course.findOne({'assignments.assignmentId': input}, {_id: 0, assignments: {$elemMatch: { assignmentId: '1'}}, CourseName: 1})
    

    您必须在项目字段的响应中添加所需的字段,就像我添加了 CourseName 一样。

    您也可以使用$ projection 运算符执行此操作,其中投影对象字段名称中的 $ 表示查询中该字段的第一个匹配数组元素的索引。

     Course.findOne({'assignments.assignmentId': input}, {_id: 0, 'assignments.$': 1,  CourseName: 1})
    

    在上述两个答案中,它将仅返回与查询匹配的第一个元素。如果有多个对象与同一分配 ID 相关,则必须使用聚合

    【讨论】:

    • 非常感谢!!!通过一点点调整,它就完美地工作了。非常感谢您快速明确的回答:)
    猜你喜欢
    • 2012-07-27
    • 2021-12-29
    • 1970-01-01
    • 2021-08-08
    • 2022-01-11
    • 1970-01-01
    • 2021-12-19
    • 2020-06-13
    • 2017-06-20
    相关资源
    最近更新 更多