保存后,猫鼬会填充

Pyk*_*ler 82 populate mongoose mongodb node.js

我不能手动或自动填充新保存的对象上的创建者字段...我能找到的唯一方法是重新查询我已经拥有的我不想做的对象.

这是设置:

var userSchema = new mongoose.Schema({   
  name: String,
});
var User = db.model('User', userSchema);

var bookSchema = new mongoose.Schema({
  _creator: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
  description: String,
});
var Book = db.model('Book', bookSchema);
Run Code Online (Sandbox Code Playgroud)

这是我拉我的头发的地方

var user = new User();
user.save(function(err) {
    var book = new Book({
        _creator: user,
    });
    book.save(function(err){
        console.log(book._creator); // is just an object id
        book._creator = user; // still only attaches the object id due to Mongoose magic
        console.log(book._creator); // Again: is just an object id
        // I really want book._creator to be a user without having to go back to the db ... any suggestions?
    });
});
Run Code Online (Sandbox Code Playgroud)

编辑:最新的mongoose解决了这个问题并添加了填充功能,请参阅新接受的答案.

use*_*684 126

您应该能够使用Model的填充函数来执行此操作:http://mongoosejs.com/docs/api.html#model_Model.populate 在book的保存处理程序中,而不是:

book._creator = user;
Run Code Online (Sandbox Code Playgroud)

你会做类似的事情:

Book.populate(book, {path:"_creator"}, function(err, book) { ... });
Run Code Online (Sandbox Code Playgroud)

可能来得太晚了,无法帮助你,但最近我被困在这个问题上,对其他人来说可能有用.

  • 这是重新查询数据库 (6认同)
  • 这将****不重新查询数据库?! (2认同)

Eri*_*oia 34

如果有人还在寻找这个.

Mongoose 3.6引入了许多很酷的功能来填充:

book.populate('_creator', function(err) {
 console.log(book._creator);
});
Run Code Online (Sandbox Code Playgroud)

要么:

Book.populate(book, '_creator', function(err) {
 console.log(book._creator);
});
Run Code Online (Sandbox Code Playgroud)

更多信息,请访问:https://github.com/LearnBoost/mongoose/wiki/3.6-Release-Notes#population

但是这样你仍然会再次查询用户.

在没有额外查询的情况下完成它的一个小技巧是:

book = book.toObject();
book._creator = user;
Run Code Online (Sandbox Code Playgroud)


Fra*_*ain 15

我的解决方案是使用execPopulate,就像这样

const t = new MyModel(value)
return t.save().then(t => t.populate('my-path').execPopulate())
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢@Francois,您挽救了我的生命,我正试图为此寻找解决方案。最后明白了。 (2认同)

Gov*_*Rai 14

返回promise(没有回调)的解决方案:

使用Document#populate

book.populate('creator').execPopulate();

// summary
doc.populate(options);               // not executed
doc.populate(options).execPopulate() // executed, returns promise
Run Code Online (Sandbox Code Playgroud)

可能的实施

var populatedDoc = doc.populate(options).execPopulate();
var populatedDoc.then(doc => {
   ... 
});
Run Code Online (Sandbox Code Playgroud)

在这里阅读文档填充.


Pra*_*hra 11

只是为了详细说明并给出另一个例子,因为它帮助了我.这可能有助于那些想要在保存后检索部分填充对象的人.该方法也略有不同.花了一两个多小时寻找正确的方法.

  post.save(function(err) {
    if (err) {
      return res.json(500, {
        error: 'Cannot save the post'
      });
    }
    post.populate('group', 'name').populate({
      path: 'wallUser',
      select: 'name picture'
    }, function(err, doc) {
      res.json(doc);
    });
  });
Run Code Online (Sandbox Code Playgroud)


小智 6

我想我会加上这个来澄清像我这样的完整新手的东西.

如果你不小心,有什么令人困惑的是,有三种截然不同的填充方法.它们是不同对象的方法(模型与文档),采用不同的输入并给出不同的输出(Document vs. Promise).

在这里,他们是那些困惑的人:

Document.prototype.populate()

查看完整的文档.

这个适用于文档并返回文档.在原始示例中,它看起来像这样:

book.save(function(err, book) {
    book.populate('_creator', function(err, book) {
        // Do something
    })
});
Run Code Online (Sandbox Code Playgroud)

因为它适用于文档并返回文档,所以您可以将它们链接在一起,如下所示:

book.save(function(err, book) {
    book
    .populate('_creator')
    .populate('/* Some other ObjectID field */', function(err, book) {
        // Do something
    })
});
Run Code Online (Sandbox Code Playgroud)

但是,不要像我一样愚蠢,并尝试这样做:

book.save(function(err, book) {
    book
    .populate('_creator')
    .populate('/* Some other ObjectID field */')
    .then(function(book) {
        // Do something
    })
});
Run Code Online (Sandbox Code Playgroud)

请记住:Document.prototype.populate()返回一个文档,所以这是无稽之谈.如果你想要一个承诺,你需要......

Document.prototype.execPopulate()

查看完整的文档.

这个适用于文档,但它返回一个解析为文档的promise.换句话说,您可以像这样使用它:

book.save(function(err, book) {
    book
    .populate('_creator')
    .populate('/* Some other ObjectID field */')
    .execPopulate()
    .then(function(book) {
        // Do something
    })
});
Run Code Online (Sandbox Code Playgroud)

那更好.最后,还有......

Model.populate()

查看完整的文档.

这个适用于模型并返回一个承诺.因此使用方式略有不同:

book.save(function(err, book) {
    Book // Book not book
    .populate(book, { path: '_creator'})
    .then(function(book) {
        // Do something
    })
});
Run Code Online (Sandbox Code Playgroud)

希望这能帮助其他一些新人.