Object.assign()Mongoose SubDocument Schema的问题

时间:2017-02-16 12:33:50

标签: node.js mongodb mongoose mongoose-schema

因此,当我在特定的Mongoose Subdocument Schema上使用Object.assign,(例如Object.assign({foo:bar1},{foo:bar2})时,foo:bar2 obj将不会覆盖foo:bar1物镜。

在我的应用程序中,我有一个帐户架构,其中包含两个子文档架构,Projects&属性。我在Project子文档架构中遇到了这个问题。

以下是我的模特:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var ProjectSchema = new Schema({
    _id: String,
    name: String,
}, { strict: false })

var PropertySchema = new Schema({
    _id: String,
    slug: String,
    name: String,
    type: String,
    placeholder: String,
    order: Number
}, { strict: false })

var AccountSchema = new Schema({
    _id: String,
    name: String,
    slug: String,
    email: String,
    properties: [PropertySchema],
    projects: [ProjectSchema],
}, { strict: false })

module.exports = mongoose.model('Account', AccountSchema);

这是我的中间件的片段(我认为这就是所谓的,如果我错了请纠正我)。这是我执行Object.assign以覆盖特定项目属性的地方。如果有帮助我可以发布所有路线。

router.route('/accounts/:account_id/projects/:project_id')

  .get(function(req, res) {
    Project.findById(req.params.project_id, function(err, project){
      if (err) 
        res.send(err);
      res.json(project);
    });
  })

  .delete(function(req, res){
    Account.findById(req.params.account_id, function(err,account){
      if (err)
        res.send(err);

      account.projects.id(req.params.project_id).remove();

      account.save(function(err) {
        if(err)
          res.send(err);
        res.json({message: 'Project Deleted'});
      });
    })
  })

  .put(function(req, res){
    Account.findById(req.params.account_id, function(err,account){
      if (err)
        res.send(err);

      Object.assign(account.projects.id(req.params.project_id), req.body);

      account.save(function(err) {
        if(err)
          res.send(err);
        res.json({message: 'Project Updated'});
      });
    })
  });

// ----------------------------------------------------
router.route('/accounts/:account_id/properties/:property_id')

  .get(function(req, res) {
    Property.findById(req.params.property_id, function(err, property){
      if(err)
        res.send(err);
      res.json(property);
    });
  })

  .delete(function(req, res){
    Account.findById(req.params.account_id, function(err, account){
      if (err)
        res.send(err);
      account.properties.id(req.params.property_id).remove();
      account.save(function(err){
        if(err)
          res.send(err);
        res.json({ message: 'Successfully Deleted' });
      })
    })
  })

  .put(function(req, res){
    Account.findById(req.params.account_id, function(err, account) {
      if (err)
        res.send(err);

      Object.assign(account.properties.id(req.params.property_id), req.body);

      account.save(function(err) {
        if(err)
          res.send(err);
        res.json({message: 'Property Updated'});
      })
    })
  });

所以这是Put方法给我的问题,我可以获取,发布,删除没有问题,但项目的Put部分是我遇到这个Object.assign问题的地方。有趣的是,一切都适用于Property Schema Put Method,它基本上和Project 1完全相同。

如果我在console.log项目的Put方法中的一些值得到以下结果:

console.log(account.projects.id(req.params.project_id));
//original value logs { _id: '1486609836741', foo: 'bar' }
console.log(req.body);
//updated value logs { foo: 'barred', _id: '1486609836741' }

console.log(Object.assign(account.projects.id(req.params.project_id), req.body));
//logs the original value { _id: '1486609836741', foo: 'bar' }

因此,当我记录更新的原始值时,它们具有相同的键,Object.assign不应该工作吗?原始Obj是否比console.log显示的更复杂,也许原始和更新没有相同的密钥?

我有点难过,任何帮助都会非常感激。如果我需要发布更多代码,请告诉我。感谢。

1 个答案:

答案 0 :(得分:0)

account.projects

在这里,您尝试分配一个对象,该对象是var project = account.projects.id( req.params.project_id ), index = account.projects.indexOf( project ); Object.assign( account.projects[ index ], req.body); 数组上MongooseDocumentArray.id方法调用的结果。这只会影响函数返回的文档副本,不会影响原始的子文档数组。

我是Mongoose的新手,但我建议您尝试使用MongooseArray上的account.projects:

<add name="InventoryEntities" 
   connectionString="metadata=res://*/Entities.csdl|res://*/Entities.ssdl|res://*/Entities.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.\sqlinstance;initial catalog=DBName;persist security info=True;user id=UID;password=PWD;MultipleActiveResultSets=True;App=EntityFramework&quot;" 
   providerName="System.Data.EntityClient" />