如何使用 mongoose 将查询结果返回给变量

use*_*051 6 mongoose mongodb node.js

我仍处于 Node.js 和 Moongoose 的学习阶段,我有一个场景

  • 我正在从表单提交中获取值(ABC)。这是一个用户名
  • 然后我在用户集合(用户)中搜索该名称
  • 使用 ref 获取该用户并将其 ObjectID 写入另一个模式(文章)中。

我的逻辑:

article.owner = User.findOne({ 'name' : 'ABC' })
    .exec(function (err, user){
         return user
    })
Run Code Online (Sandbox Code Playgroud)

但它没有返回结果。我参考了其他一些答案并尝试过,async.parallel但我仍然无法在文章架构中保存 ABC 用户的 objectID,因为article.owner我总是为空。

请建议我任何其他更好的方法。

C B*_*ard 3

当 Node 必须执行任何 I/O(例如从数据库读取)时,它将异步完成。User.findOne诸如和 之类的方法Query#exec永远不会预先返回结果,因此article.owner在您的示例中不会正确未定义。

异步查询的结果仅在回调内部可用,该回调仅在 I/O 完成时调用

article.owner = User.findOne({ name : 'ABC' }) .exec(function (err, user){    
    // User result only available inside of this function!
    console.log(user) // => yields your user results
})

// User result not available out here!
console.log(article.owner) // => actually set to return of .exec (undefined)
Run Code Online (Sandbox Code Playgroud)

异步代码执行在上面的示例中意味着什么:当 Node.js 命中时,article.owner = User.findOne...它将执行User.findOne().exec(),然后直接移至console.log(article.owner)之前.exec完成的位置。

希望这有助于澄清。需要一段时间才能习惯异步编程,但通过更多练习就会有意义

更新要回答您的具体问题,一种可能的解决方案是:

User.findOne({name: 'ABC'}).exec(function (error, user){
    article.owner = user._id; // Sets article.owner to user's _id
    article.save()            // Persists _id to DB, pass in another callback if necessary
});
Run Code Online (Sandbox Code Playgroud)

如果您想向用户加载文章,请记住使用Query#populate,如下所示:

Article.findOne({_id: <some_id>}).populate("owner").exec(function(error, article) {
    console.log(article.owner); // Shows the user result
});
Run Code Online (Sandbox Code Playgroud)