Mongoose,更新对象数组中的值

时间:2013-03-28 20:09:01

标签: node.js mongodb mongoose

有没有办法更新对象中的值?

{
  _id: 1,
  name: 'John Smith',
  items: [{
     id: 1,
     name: 'item 1',
     value: 'one'
  },{
     id: 2,
     name: 'item 2',
     value: 'two'
  }]
}

假设我想更新项目的名称和值项目,其中id = 2;

我尝试过以下w / mongoose:

var update = {name: 'updated item2', value: 'two updated'};
Person.update({'items.id': 2}, {'$set':  {'items.$': update}}, function(err) { ...

这种方法的问题在于它更新/设置整个对象,因此在这种情况下我丢失了id字段。

在mongoose中有更好的方法在数组中设置某些值但是只留下其他值吗?

我也只是询问了人:

Person.find({...}, function(err, person) {
  person.items ..... // I might be able to search through all the items here and find item with id 2 then update the values I want and call person.save().
});

11 个答案:

答案 0 :(得分:112)

你很亲密;您应该在使用$ update operator时使用点表示法来执行此操作:

Person.update({'items.id': 2}, {'$set': {
    'items.$.name': 'updated item2',
    'items.$.value': 'two updated'
}}, function(err) { ...

答案 1 :(得分:10)

model.update({"_id": 1, "items.id": "2"}, 
{$set: {"items.$.name": "yourValue","items.$.value": "yourvalue"}})

Mongodb document

答案 2 :(得分:4)

对于每个文档,更新运算符$set都可以set multiple values,因此您可以设置items和{{name数组,而不是替换value数组中的整个对象。 1}}对象的字段。

{'$set':  {'items.$.name': update.name , 'items.$.value': update.value}}

答案 3 :(得分:2)

下面是如何更动态地更新对象数组中的值的示例。

Person.findOneAndUpdate({_id: id}, 
{ 
  "$set": {[`items.$[outer].${propertyName}`]: value} 
},
{ 
  "arrayFilters": [{ "outer.id": itemId }]
},
function(err, response) {
  ...
})

请注意,通过这样做,您可以通过添加其他arrayFilters来更新嵌套数组的更深层次,如下所示:

"$set": {[`items.$[outer].innerItems.$[inner].${propertyName}`]: value} 

"arrayFilters":[{ "outer.id": itemId },{ "inner.id": innerItemId }]

我希望它会有所帮助。祝你好运!

答案 4 :(得分:0)

在Mongoose中,我们可以使用点($set)表示法中的.将数组值更新为以下方式的特定值

db.collection.update({"_id": args._id, "viewData._id": widgetId}, {$set: {"viewData.$.widgetData": widgetDoc.widgetData}})

答案 5 :(得分:0)

在mongoose中我们可以像简单数组一样更新

user.updateInfoByIndex(0,"test")

User.methods.updateInfoByIndex = function(index, info) ={
    this.arrayField[index]=info
    this.save()
}

答案 6 :(得分:0)

update(
    {_id: 1, 'items.id': 2},
    {'$set': {'items.$[]': update}},
    {new: true})

这是有关$[]的文档。

答案 7 :(得分:0)

要记住一件事,当您基于多个条件在数组中搜索对象时,请使用 $ elemMatch

Person.update(
   {
     _id: 5,
     grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } }
   },
   { $set: { "grades.$.std" : 6 } }
)

这是docs

答案 8 :(得分:0)

有一种猫鼬的方法。

const itemId = 2;
const query = {
  item._id: itemId 
};
Person.findOne(query).then(doc => {
  item = doc.items.id(itemId );
  item["name"] = "new name";
  item["value"] = "new value";
  doc.save();

  //sent respnse to client
}).catch(err => {
  console.log('Oh! Dark')
});

答案 9 :(得分:0)

尝试了其他效果很好的解决方案,但是他们的答案的陷阱是,只有已经存在的字段会更新,向其中添加upsert不会起作用,所以我想到了这一点。

 Person.update({'items.id': 2}, {$set: {
    'items': { "item1",  "item2",  "item3",  "item4" } }, {upsert: 
true })

答案 10 :(得分:0)

我有类似的问题。这是最干净的方法。

NAME                          TYPE           CLUSTER-IP       EXTERNAL-IP                          PORT(S)
loadbalancer-ingressgateway   LoadBalancer   172.30.68.12     xxxxxx.ap-northeast-1.elb.amazonaws.com   15021:30053/TCP,80:31829/TCP,443:32661/TCP,15443:30937/TCP