我在MongoDB中使用深层嵌套数组时遇到了一些困难。我使用的是mongoose,我的项目包含所有当前使用相同数据库集合的微服务。是否可以使用下面的示例来嵌套它有多深?如果是,那么如何访问"questionUser"
,"questionTitle"
或"questionContent"
。我目前能够添加课程和课程标题。当我尝试添加问题数据时,正确的路由器会受到攻击,但它只是挂起并超时,所有数据都是null
。
我已经压缩了下面的数据示例。我正在使用MEAN堆栈。我也没有看到任何错误,它只是悬挂。不确定在何处或如何开始对此进行故障排除。我并不反对重新设计我的数据库,但是我想以某种方式继续使用嵌套/嵌入式结构,但需要一些关于如何改变它的指导。
数据库
{
"_id": "593bc9fbbc083a8200eb9b36",
"courseTitle": "Course 101",
"courseActive": true,
"lessons": [
{
"lessonTitle": "Lesson about widgets",
"_id": "593bcecc0799cd89a87ce53e",
"lessonActive": true,
"questions": [
{
"questionUser": "user1",
"_id" : "dadsfjlkj23o21",
"questionTitle": "title",
"questionContent": "stuffff",
"answers" : [
{
"answerUser": "user2",
"_id": "asdfk231191837d",
"answerContent": "the answer is simple",
"comment": [
{
"commentUser": "user1",
"_id": "asdkjfawow8183",
"commentBody": "That makes sense, thanks!"
}
]
}
]
}
]
}
]
}
路由器
/*
* create new course
*/
router.post('/', (req, res) => {
let course = new Course();
course.courseTitle = req.body.courseTitle;
course.courseActive = req.body.courseActive;
course.save().then((saveCourse) => res.json(saveCourse))
.catch((err) => console.log(err));
});
/*
* create new lesson
*/
router.post('/:id', (req, res) => {
Course.findOne({_id: req.params.id}).then((foundCourse) => {
foundCourse.lessons = req.body.lessons;
foundCourse.save().then((savedCourse) => res.json(savedCourse))
.catch((err) => console.log(err));
})
});
/*
* create new question
*/
router.post('/:id/lessons/:lessonid', (req, res) => {
Lesson.findOne({_id: req.params.id}).then((foundLesson) => {
foundLesson.questions = req.body.questions;
foundLesson.save().then((savedLesson) => res.json(savedLesson))
.catch((err) => console.log(err));
})
});
app.ts
import courses from './api/courses';
app.use('/api/v2/courses', courses);
import lessons from './api/lessons';
app.use('/api/v2/lessons', lessons);
import questions from './api/questions';
app.use('/api/v2/questions', questions);
答案 0 :(得分:3)
肯定有办法对这种嵌套的MODEL进行操作。
用于查找文件mongoose提供更好的聚合方案和事件AGGREGATION。
创建文档时,我认为不会出现问题。 更新文档时,您需要子文档和子子文档的_id。
Model.findOneById("").then((data) => {
if (!data) return res.status(401).json({ "err": "not found" });
var lesson = data.lessons.id("lessionId");
if (!lesson) return res.status(401).json({ "err": "not found!!" });
var question = lession.id("QustionId");
if (!question) return res.status(401).json({ "err": "not found!!" });
var answer = answer.id("AnswerId");
if (!answer ) return res.status(401).json({ "err": "not found!!" });
var comment = answer.id("commentId");
if (!comment ) return res.status(401).json({ "err": "not found!!" });
comment.commentUser: "user1",
comment.commentBody: "That makes sense, thanks!"
data.save().then((success) => {
return res.status(200).json("success");
}).catch((err) => {
return res.status(500).json(err);
});
}).catch((err) => {
return res.status(500).jsonp(err);
});
1。)这样可以正常工作,但它也会降低性能,因为它会获取整个文档然后重写它,所以最好不要使用这种操作, 2.)还要记住 16MB 限制/文件
还有其他方法可以提高性能 ==>参考模型
您可以将模型从一个集合设计为 TWO ,或者可以在参考系统中 THREE ,并且可以使用聚合功能来引用系统 Aggrigation docs of mongodb, Populate of Mongoose
希望这会有所帮助.. 谢谢
答案 1 :(得分:1)
您需要以这种方式访问它们:
lessons.lessonTitle
lessons.questions.questionUser
lessons.questions.answers.answerUser
lessons.questions.answers.comment.commentUser
只需修改与示例相同级别的其他键的最后一个键名称。
MongoDB对更新嵌套数组的支持很差。因此,如果您需要经常更新数据并考虑使用多个集合,那么最好避免使用它们。但是,对此也存在争议。您可以在Embed vs Reference上阅读更多内容,并确定最适合您需求的内容。