Node.js - Mongoose - 使用req.body

时间:2016-07-08 19:28:48

标签: javascript node.js mongodb express mongoose

我有一个看起来像这样的对象。

{
  _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'
        }
      ]
    }
  ]
}

我的目标是引用competitors数组并使用req.body中的所有值更新内部的项目。我的代码基于this回答,以及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);
    }
  }
);

我将HTTP PUT发送给localhost:3000/competitors/577fe7a842c9bd6d以更新彼得的银徽章。请求正文是:

{
  "name": "McDonald's"
}

问题在于,当我使用$set设置竞争对手_id: req.params.competitorId时,我不知道req.body中的内容。我想使用整个req.body来更新数组中的对象,但是当我这样做时,该对象被覆盖,因此彼得的Silver Badges不会获得新名称,而是变成:

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

如果我知道_id对象req.body中包含sites的所有字段而不删除我想要保留的字段,那么如何更新数组中的对象?

我认为sites: [sitesSchema]数组为空,因为该对象已重新初始化。在我的架构中,我有competitors[_id]来初始化它。所以我假设整个sites: [sitesSchema]对象被新名称覆盖,然后是来自myschema的adb.mac

2 个答案:

答案 0 :(得分:8)

您需要在$中使用$set位置运算符。要根据req.body中的内容动态分配这些属性,您需要以编程方式构建$set

如果您想更新名称,请执行以下操作:

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);
    }
 }
);

使用$set以编程方式构建req.body的一种方法是执行以下操作:

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

有关详细信息,请参阅this答案。

答案 1 :(得分:1)

要使用$运算符更新嵌入式文档,在大多数情况下,您必须在$运算符上使用点表示法。

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);
    }
  }
);