ModeMongoose 的 Async/Await with Mongoose Deep Populate Chain
ModeMongoose's Async/Await with Mongoose Deep Populate Chain
在使用 async/await 时,我在按顺序获取链式猫鼬命令 运行 时遇到了很多麻烦。一个简单的 await Model.find({})
命令可以像人们预期的那样在异步函数中工作,但是当我为了深度填充的目的将 find 命令与 lean
、populate
和 exec
链接时( http://mongoosejs.com/docs/populate.html#deep-populate) 我无法 运行 按我想要的顺序排列它们。
const messageSchema = new Schema({
...
})
const Message = mongoose.model("message", messageSchema)
const chatSchema = new Schema({
conversations: [{
messages: [{ type: Schema.Types.ObjectId, ref: "message" }]
}]
})
const Chat = mongoose.model("chat", phoneSchema)
console.log("11111111111")
const chat = await Chat.findOne({ ... })
.lean()
.populate({ path: "conversations" })
.exec(async (err, docs) => {
const options = {
path: "conversations.messages",
model: "message",
}
const result = await Chat.populate(docs, options,
(e, foundChat) => foundChat)
console.log("22222222222")
return result
})
console.log("333333333333")
结果:
11111111
33333333
22222222
期望的结果:
111111111
222222222
333333333
不知道为什么,尝试了很多不同的东西,但这很有效。
const chat = await Chat.findOne({ ... })
.populate({
path: "conversations.messages",
model: "message",
})
.exec((error, foundChat) => foundChat)
我觉得你的代码有 2 个问题:
使用 lean() 选项后不能调用 populate()。 Lean() 将 returned 对象变成常规 javascript 对象而不是 mongoose 文档。 Populate是mongoose内置的方法,所以只能在mongoose文档中使用。这与您的问题无关,但了解这一点很重要。
当您在查询上调用 exec() 并将回调作为参数传递时,它不会 return 承诺,因此 'await' 子句对其没有影响.这就是为什么您的函数不等待 Chat.findOne() 解析并直接进入最后一个 console.log 的原因。以下可能会起作用:
const chat = await Chat.findOne({ ... })
.populate({ path: "conversations" })
.exec().then(async (docs) => {
const options = {
path: "conversations.messages",
model: "message",
}
const result = await Chat.populate(docs, options)
console.log("22222222222")
return result
})
在使用 async/await 时,我在按顺序获取链式猫鼬命令 运行 时遇到了很多麻烦。一个简单的 await Model.find({})
命令可以像人们预期的那样在异步函数中工作,但是当我为了深度填充的目的将 find 命令与 lean
、populate
和 exec
链接时( http://mongoosejs.com/docs/populate.html#deep-populate) 我无法 运行 按我想要的顺序排列它们。
const messageSchema = new Schema({
...
})
const Message = mongoose.model("message", messageSchema)
const chatSchema = new Schema({
conversations: [{
messages: [{ type: Schema.Types.ObjectId, ref: "message" }]
}]
})
const Chat = mongoose.model("chat", phoneSchema)
console.log("11111111111")
const chat = await Chat.findOne({ ... })
.lean()
.populate({ path: "conversations" })
.exec(async (err, docs) => {
const options = {
path: "conversations.messages",
model: "message",
}
const result = await Chat.populate(docs, options,
(e, foundChat) => foundChat)
console.log("22222222222")
return result
})
console.log("333333333333")
结果:
11111111
33333333
22222222
期望的结果:
111111111
222222222
333333333
不知道为什么,尝试了很多不同的东西,但这很有效。
const chat = await Chat.findOne({ ... })
.populate({
path: "conversations.messages",
model: "message",
})
.exec((error, foundChat) => foundChat)
我觉得你的代码有 2 个问题:
使用 lean() 选项后不能调用 populate()。 Lean() 将 returned 对象变成常规 javascript 对象而不是 mongoose 文档。 Populate是mongoose内置的方法,所以只能在mongoose文档中使用。这与您的问题无关,但了解这一点很重要。
当您在查询上调用 exec() 并将回调作为参数传递时,它不会 return 承诺,因此 'await' 子句对其没有影响.这就是为什么您的函数不等待 Chat.findOne() 解析并直接进入最后一个 console.log 的原因。以下可能会起作用:
const chat = await Chat.findOne({ ... }) .populate({ path: "conversations" }) .exec().then(async (docs) => { const options = { path: "conversations.messages", model: "message", } const result = await Chat.populate(docs, options) console.log("22222222222") return result })