Javascript 单链查询mongodb/mongoose以获取所有注释
我正试图开发一个个人项目,一个网站,以一种类似的方式来堆叠交换,用户可以问一个问题,可以得到多个答案。每个问题和答案可以有多个注释Javascript 单链查询mongodb/mongoose以获取所有注释,javascript,node.js,mongodb,mongoose,aggregation-framework,Javascript,Node.js,Mongodb,Mongoose,Aggregation Framework,我正试图开发一个个人项目,一个网站,以一种类似的方式来堆叠交换,用户可以问一个问题,可以得到多个答案。每个问题和答案可以有多个注释 db.questions.aggregate([ {"$match":{"_id":input_question_id}}, {"$lookup":{ "from":"answers", "localField":"
db.questions.aggregate([
{"$match":{"_id":input_question_id}},
{"$lookup":{
"from":"answers",
"localField":"_id",
"foreignField":"questionId",
"as":"answers"
}},
{"$lookup":{
"from":"comments",
"let":{"ids":{"answers_id":"$answers._id","question_id":"$_id"}},
"pipeline":[
{"$match":{"$expr":{
"$or":[
{"$eq":["$idQuestion","$$ids.question_id"]},
{"$in":["$idAnswer","$$ids.answers_id"]}
]
}}}
],
"as":"comments"
}},
{"$project":{"comments":"$comments.content"}}
])
我使用nodeJS作为后端
如何在单个mongoDB/mongoose查询中获取特定问题的答案的all注释
如果您能告诉我如何在单个mongoDB/mongoose查询中获取某个特定问题的答案的all注释以及该问题的all注释,那将更有帮助
猫鼬模式:
const questionSchema = new mongoose.Schema({
title: String,
content: String
})
const answerSchema = new mongoose.Schema({
questionId: String,
content: String,
})
const commentSchema = new mongoose.Schema({
idQuestion: String, // nullable
idAnswer: String, // nullable
content: String
})
目前,我正在执行mongoose查询,以查找特定问题的所有答案。然后,使用
forEach
,对每个答案执行mongoose查询,以查找每个答案的所有注释。我认为这是一种非常繁重的、性能方面的工作,并且不是实现我想要实现的目标的理想方式。您可以在下面尝试。匹配问题id,然后连接以查找所有答案id,然后使用问题id查找以提取所有注释
db.questions.aggregate([
{"$match":{"_id":input_question_id}},
{"$lookup":{
"from":"answers",
"localField":"_id",
"foreignField":"questionId",
"as":"answers"
}},
{"$lookup":{
"from":"comments",
"let":{"ids":{"answers_id":"$answers._id","question_id":"$_id"}},
"pipeline":[
{"$match":{"$expr":{
"$or":[
{"$eq":["$idQuestion","$$ids.question_id"]},
{"$in":["$idAnswer","$$ids.answers_id"]}
]
}}}
],
"as":"comments"
}},
{"$project":{"comments":"$comments.content"}}
])
这里的工作示例-您可以尝试
您的条件$match
问题ID
- 加入
评论
第二种方法,如果您想选择包含所有答案和评论的问题,请尝试
您的条件$match
- 加入
集合答案
- pipeline字段允许添加我们在根级别使用的管道的所有阶段
问题ID并获取答案$match
加入注释集合$lookup
显示或隐藏额外字段,您可以在上述查询结束时使用运算符
- 您可以根据需要显示字段
建议: 我不确定,您是否已经这样做了,但尝试在引用字段中定义对象id类型而不是字符串类型,就像我更新了您的模式一样,这将在对象id中添加默认索引,这将提高获取数据的速度
const answerSchema = new mongoose.Schema({
questionId: mongoose.Types.ObjectId,
content: String,
})
const commentSchema = new mongoose.Schema({
idQuestion: mongoose.Types.ObjectId, // nullable
idAnswer: mongoose.Types.ObjectId, // nullable
content: String
})
似乎您正在将Mongo实例视为关系数据库,您是否考虑过将答案嵌入问题中,并在答案中添加注释(假设答案是这样的)?@Nimnam1我想这样做,但是我想知道我的设置方式是否可行?看看如果这不能回答你的问题,我可以看看我是否能想出一些东西。你使用Mongo的方式不对,你应该对你的数据进行非规范化。非常感谢!你能再解释一下管道是什么吗?我不是mongodb方面的专家,我真的不明白它是什么?它是否从以前的
$lookup
和“通过管道推送”中获取结果以用于另一个操作?这是一个聚合查询,在内部,我们使用了单独的对象和特定的操作符,称为管道阶段,$lookup
是一个管道操作符,用于连接特定集合并返回数组字段中的匹配数据,有两种类型的查找,一种是我们在第一次查询中使用的简单查找,另一种是管道查找,我们可以使用管道字段,并在管道字段中添加任何管道阶段。我认为op需要问题和所有答案的评论。您可以在一个查询中完成,如我的答案所示。@svr我不确定,他没有提到,根据我的理解,我提供了两个选项,他在第一次评论中看起来很满意。我认为他不太清楚自己的期望,也是聚合查询方面的新手。@turivishal在第二种方法中,您是否也能获取问题的评论?
{
$project: {
_id: 1,
content: 1,
"comments._id": 1,
"comments.content": 1
}
}
const answerSchema = new mongoose.Schema({
questionId: mongoose.Types.ObjectId,
content: String,
})
const commentSchema = new mongoose.Schema({
idQuestion: mongoose.Types.ObjectId, // nullable
idAnswer: mongoose.Types.ObjectId, // nullable
content: String
})