如何访问 MongoDB 文档中数组中的对象?
How to access an object within an array within a MongoDB document?
-- 底部的答案 --
我和我的项目合作伙伴正在尝试弄清楚如何访问数组中的对象,即我们 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' }
)
这是我们的主要模型,称为课程,在作业内部(如您所见),我们将子文档作为数组中的另一个模式传入:
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,然后导航到我们的 generic/dynamically填充的作业页面,但特别是我们的 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(或查找)方法无法正常工作,returns 整个 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);
});
您可以在项目选项中使用 $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})
在上面的两个答案中,它 return 只有第一个元素与查询匹配。如果有多个对象与同一个分配 ID 相关,则必须使用 aggregate
-- 底部的答案 --
我和我的项目合作伙伴正在尝试弄清楚如何访问数组中的对象,即我们 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' }
)
这是我们的主要模型,称为课程,在作业内部(如您所见),我们将子文档作为数组中的另一个模式传入:
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,然后导航到我们的 generic/dynamically填充的作业页面,但特别是我们的 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(或查找)方法无法正常工作,returns 整个 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);
});
您可以在项目选项中使用 $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})
在上面的两个答案中,它 return 只有第一个元素与查询匹配。如果有多个对象与同一个分配 ID 相关,则必须使用 aggregate