我从mongodb中获得了一个文档,其中包含一个带有对该文档的注释的数组。注释中是编写注释的用户的_id。
我现在需要根据用户的_id获取用户名,但是我遇到了一些问题。
我有以下代码,这些代码显然不起作用,但是我希望它可以使您了解我要完成的工作。
//MORE CODE... (No need to show this here, just a promise, some try catch and so on)
let article = await Article.findOne({_id:articleid})
for(var i = 0; i<=article.comment.length-1; i++){
User.findOne({_id:article.comment[i].user}).then((user)=>{
article.comment[i].username = user.username
})
}
return resolve(article)
我查阅了一些文档,但找不到有效的解决方案。我尝试使用Promise.all,并进行了许多异步处理,等待,试图在for循环中添加一个计数器,并在循环结束后解决了Promise,但到目前为止没有任何效果。
这就是我的数据库中的文章
{
"_id" : ObjectId("5c18c1cbc47e5e29d42e4b0e"),
"completed" : false,
"completedAt" : null,
"comment" : [
{
"_id" : ObjectId("5c18c95e328c8319ac07d817"),
"comment" : "This is a comment",
"rating" : [ ],
"user" : ObjectId("5c18b76e73236d2168eda2b4")
},
{
"_id" : ObjectId("5c18fb578de5741f20a4e2bd"),
"comment" : "Another comment",
"rating" : [ ],
"user" : ObjectId("5c18b76e73236d2168eda2b4")
}
]
}
我对Node.js和mongodb还是很陌生,所以希望您能帮助像我这样的新手。
感谢您的帮助
答案 0 :(得分:3)
您可以根据自己的方便在这里使用一些服务器方法
使用异步等待
let article = await Article.findOne({ _id: articleid }).lean().exec()
await Promise.all(
article.comment.map(async(obj) => {
const user = await User.findOne({ _id: obj.user })
obj.username = user.username
})
)
console.log(article)
使用$lookup
聚合3.6
由于mongodb具有自己强大的$lookup
聚合运算符,可以加入多个集合,并且可能是无需任何迭代的更好方法
Article.aggregate([
{ "$match": { "_id": mongoose.Types.ObjectId(articleid) }},
{ "$unwind": "$comment" },
{ "$lookup": {
"from": "users",
"let": { "userId": "$comment.user" },
"pipeline": [
{ "$match": { "$expr": { "$eq": ["$$userId", "$_id"] }}}
],
"as": "comment.user"
}},
{ "$unwind": "$comment.user" },
{ "$group": {
"_id": "$_id",
"comment": { "$push": "$comment" },
"completed": { "$first": "$completed" },
"completedAt": { "$first": "$completedAt" }
}}
])
使用$lookup
聚合3.4
Article.aggregate([
{ "$match": { "_id": mongoose.Types.ObjectId(articleid) }},
{ "$unwind": "$comment" },
{ "$lookup": {
"from": "users",
"localField": "comment.user",
"foreignField": "_id",
"as": "comment.user"
}}
{ "$unwind": "$comment.user" },
{ "$group": {
"_id": "$_id",
"comment": { "$push": "$comment" },
"completed": { "$first": "$completed" },
"completedAt": { "$first": "$completedAt" }
}}
])
答案 1 :(得分:-2)
您可以按照以下方式尝试
const d = {
"_id" : ObjectId("5c18c1cbc47e5e29d42e4b0e"),
"completed" : false,
"completedAt" : null,
"comment" : [
{
"_id" : ObjectId("5c18c95e328c8319ac07d817"),
"comment" : "This is a comment",
"rating" : [ ],
"user" : ObjectId("5c18b76e73236d2168eda2b4")
},
{
"_id" : ObjectId("5c18fb578de5741f20a4e2bd"),
"comment" : "Another comment",
"rating" : [ ],
"user" : ObjectId("5c18b76e73236d2168eda2b4")
}
]
}
d.comment.forEach( async (obj, index) => {
await new Promise((res) => {
obj.counter = index;
res();
})
});
console.log(d);
作为参考,请查看以下链接 Asycn/Await using forEach