在Mongoose中保存填充值

时间:2015-02-18 05:35:27

标签: node.js backbone.js express mongoose marionette

如果我在将文档发送到客户端之前获取文档并填充它,那么在进行更新时减少这些字段的最佳方法是什么?

模式:

var User = new mongoose.Schema({
  name: String
});

var Post = new mongoose.Schema({
  title: String,
  likes: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User'
  }]
});

控制器:

app.get('/post/:id', function (req, res, next) {
  Post.findById(req.params.id).populate('likes').exec(function (err, post) {
    if (err) return next(err);
    res.json(post);
  });
});

app.put('/post/:id', function (req, res, next) {
  Post.findById(req.params.id, function (err, post) {
    if (err) return next(err);

    _.extend(post, req.body);
    post.save(function (err) {
      if (err) return next(err);
      res.json(post);
    });
  });
});

所以在客户端我收到的内容如下:

{
  _id: 123,
  title: 'Test post',
  likes: [{
    _id: 456,
    name: 'John Doe'
  }, {
    _id: 789,
    name: 'Max Danger'
  }]
}

哪一切都很好。但是当我在客户端修改模型时(我正在使用Backbone.Marionette FWIW),然后将其保存回来,Mongoose会抛出Cast to ObjectId failed for value "[object Object],456" at path "likes"错误。

我认为Mongoose可以自动从这些对象中抓取_id,但它似乎不会那样工作..?

那么这里最好的方法是什么?在发送到服务器之前,我应该在客户端上获取ID吗?或者在调用save之前我是否可以使用服务器?

此外,保存后我需要重新填充这些字段,然后再将保存的产品发回客户端,对吗?

最后,我认为我实际不能使用Mongoose的depopulate()方法,因为我从客户端接收时只有JSON,而不是实际的Model实例。

任何帮助..?谢谢!

2 个答案:

答案 0 :(得分:0)

您可以使用节点的下划线库,而不是使用mongoose的depopulate()方法,它提供函数pick并返回给定对象的选择值并更快地计算结果here is example

app.get('/post/:id', function (req, res, next) {

Post.findById(req.params.id).populate('likes').exec(function (err, post) {

if (err) return next(err);

 var depopulate  = _.pick(post, '_id');

 res.json(depopulate);

});
});

depopulate变量将从查询结果文档中存储_id's  您可以轻松地将所有_id's发送给客户。

答案 1 :(得分:0)

我知道这个问题是在2年前发布的,但我认为它可能对你有帮助.. 您可以覆盖一些预定义的方法来完成您所需的工作。

UserSchema.methods.toJSON = function () {

    var user = this.toObject();  
    return _.pick(user, ['_id', 'email']);

};

就像我重写了toJSON方法只发送_id和电子邮件而不是发回整个用户doc。