简体   繁体   English

Node.js-猫鼬-使用req.body中的所有值更新嵌套数组

[英]Node.js - Mongoose - Update nested array with all values in req.body

I have an object that looks like this. 我有一个看起来像这样的对象。

{
  _id: '577fe7a842c9b447',
  name: 'Jacob\'s Bronze Badges',
  competitors: [
    {
      _id: '577fe7a842c9bd6d',
      name: 'Peter\'s Silver Badges',
      sites: [
        {
          _id: '577fe7a842c9bd6d',
          name: 'Facebook',
          url: 'fb.com/peter'
        },
        {
          _id: '577fe7a842c9bd6d'
          name: 'Google',
          url: 'google.com/peter'
        }
      ]
    },
    {
      _id: '599fe7a842c9bd6d',
      name: 'Paul\'s Gold Badges',
      sites: [
        {
          '_id': '577fe7a842c9bd6d',
          name: 'Facebook',
          url: 'fb.com/paul'
        },
        {
          _id: '577fe7a842c9bd6d',
          name: 'Google',
          url: 'google.com/paul'
        }
      ]
    }
  ]
}

My goal is to reference the competitors array and update items inside with all of the values from req.body . 我的目标是引用competitors数组,并使用req.body所有值更新项目。 I based this code off of this answer, as well as this other one . 我基于这个代码关闭的这个答案,以及该另一个

Location.update(
  { 'competitors._id': req.params.competitorId, },
  { $set: { 'competitors.$': req.body, }, },
  (err, result) => {
    if (err) {
      res.status(500)
      .json({ error: 'Unable to update competitor.', });
    } else {
      res.status(200)
      .json(result);
    }
  }
);

I send my HTTP PUT to localhost:3000/competitors/577fe7a842c9bd6d to update Peter's Silver Badges. 我将HTTP PUT发送到localhost:3000/competitors/577fe7a842c9bd6d以更新Peter的Silver localhost:3000/competitors/577fe7a842c9bd6d The request body is: 请求正文为:

{
  "name": "McDonald's"
}

The problem is that when I use $set to set the competitor with _id: req.params.competitorId , I don't know what is in req.body . 问题是,当我使用$set设置具有_id: req.params.competitorId的竞争对手_id: req.params.competitorId ,我不知道req.body什么。 I want to use the entire req.body to update the object in the array, but when I do, that object is overwritten, so instead of getting a new name, Peter's Silver Badges becomes: 我想使用整个req.body来更新数组中的对象,但是当我这样做时,该对象将被覆盖,因此,Peter的Silver Badges不再使用新名称,而是变为:

{
  name: 'McDonald\'s',
  sites: []
}

How can I update an object within an array when I know the object's _id with all of the fields from req.body without removing fields that I want to keep? 当我知道对象的_idreq.body所有字段而又不删除要保留的字段时,如何更新数组中的对象?

I believe that the sites array is empty because the object was reinitialized. 我相信由于对象已重新初始化,所以sites数组为空。 In my schema I have sites: [sitesSchema] to initialize it. 在我的架构中,我具有以下sites: [sitesSchema]进行初始化。 So I am assuming that the whole competitors[_id] object is getting overwritten with the new name and then the sites: [sitesSchema] from myschema. 因此,我假设整个competitors[_id]对象都将被新名称和sites: [sitesSchema]覆盖sites: [sitesSchema] myschema中的sites: [sitesSchema]

You would need to use the $ positional operator in your $set . 您将需要在$set使用$位置运算符。 In order to assign those properties dynamically, based on what is in your req.body , you would need to build up your $set programmatically. 为了基于req.body内容动态分配这些属性,您需要以编程方式构建$set

If you want to update the name you would do the following: 如果要更新名称,请执行以下操作:

Location.update(
  { 'competitors._id': req.params.competitorId },
  { $set:  { 'competitors.$.name': req.body.name }},
  (err, result) => {
    if (err) {
      res.status(500)
      .json({ error: 'Unable to update competitor.', });
    } else {
      res.status(200)
      .json(result);
    }
 }
);

One way you might programatically build up the $set using req.body is by doing the following: 您可以使用req.body以编程方式构建$set一种方法是执行以下操作:

let updateObj = {$set: {}};
for(var param in req.body) {
  updateObj.$set['competitors.$.'+param] = req.body[param];
 }

See this answer for more details. 有关更多详细信息,请参见此答案。

To update embedded document with $ operator, in most of the cases, you have to use dot notation on the $ operator. 要使用$运算符更新嵌入式文档,在大多数情况下,必须在$运算符上使用点符号。

Location.update(
  { _id: '577fe7a842c9b447', 'competitors._id': req.params.competitorId, },
  { $set: { 'competitors.$.name': req.body.name, }, },
  (err, result) => {
    if (err) {
      res.status(500)
      .json({ error: 'Unable to update competitor.', });
    } else {
      res.status(200)
      .json(result);
    }
  }
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM