我有一个看起来像这样的对象。
{
_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
。
答案 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);
}
}
);