sourcetip

Mongoose, 개체 배열에서 값 업데이트

fileupload 2023. 3. 14. 21:50
반응형

Mongoose, 개체 배열에서 값 업데이트

오브젝트의 값을 갱신하는 방법이 있습니까?

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

항목의 이름 및 값 항목을 업데이트하려고 합니다(ID = 2).

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

근접했습니다. 업데이트 연산자를 사용할 때 점 표기법을 사용해야 합니다.

Person.update({'items.id': 2}, {'$set': {
    'items.$.name': 'updated item2',
    'items.$.value': 'two updated'
}}, function(err) { ...
model.update(
    { _id: 1, "items.id": "2" },
    {
        $set: {
            "items.$.name": "yourValue",
            "items.$.value": "yourvalue",
         }
    }
)

MongoDB 문서

그것을 하는 데는 망구스 방법이 있다.

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

주의할 점이 하나 있습니다.여러 조건에 따라 배열된 객체를 검색할 때는 $elemMatch를 사용합니다.

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

여기 문서가 있습니다.

각 문서에 대해 업데이트 연산자$set여러 개의 값을 설정할 수 있기 때문에 오브젝트 전체를 치환할 필요가 없습니다.items어레이를 설정할 수 있습니다.name그리고.value오브젝트의 필드를 개별적으로 표시합니다.

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

다음은 개체 배열의 값을 보다 동적으로 업데이트하는 방법의 예입니다.

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 }]

더 많은 사용법은 공식 문서에서 찾을 수 있습니다.

클리너 솔루션 사용findOneAndUpdate

  await Person.findOneAndUpdate(
    { _id: id, 'items.id': 2 },
    {
      $set: {
        'items.$.name': 'updated item2', 
        'items.$.value': 'two updated',
      }
    },
   );

Mongoose에서는 어레이 값을 업데이트할 수 있습니다.$set안쪽 점().특정 값에 대한 표기법은 다음과 같습니다.

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

다른 솔루션을 시도해 본 결과, 정상적으로 동작하고 있었지만, 기존의 필드만 갱신해 버리면 아무것도 할 수 없기 때문에, 이것을 생각해 냈습니다.

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

저도 비슷한 문제가 있었어요.여기 그것을 하는 가장 깨끗한 방법이 있다.

    const personQuery = {
       _id: 1  
    }

    const itemID = 2;

    Person.findOne(personQuery).then(item => {
       const audioIndex = item.items.map(item => item.id).indexOf(itemID);
       item.items[audioIndex].name = 'Name value';
       item.save();
    });

도트 오브젝트를 사용하여 이 솔루션을 찾았는데 도움이 되었습니다.

import dot from "dot-object";

const user = await User.findByIdAndUpdate(id, { ...dot.dot(req.body) });

동적 키와 값의 쌍을 사용하여 어레이 요소를 업데이트해야 했습니다.업데이트 개체를 를 포함하는 새 키에 매핑함으로써$update operator. 어레이 요소의 업데이트된 키를 더 이상 알 필요가 없으며 대신 새로운 업데이트 개체를 즉시 조립할 수 있습니다.

update = {
  name: "Andy",
  newKey: "new value"
}
new_update = Object.fromEntries(
  Object.entries(update).map(
    ([k, v], i) => ["my_array.$." + k, v]
  )
)
console.log({
  "$set": new_update
})

mongoose에서는 심플한 어레이처럼 업데이트를 할 수 있습니다.

user.updateInfoByIndex(0,"test")

User.methods.updateInfoByIndex = function(index, info) ={
    this.arrayField[index]=info
    this.save()
}
update(
    {_id: 1, 'items.id': 2},
    {'$set': {'items.$[]': update}},
    {new: true})

여기 에 대한 문서가 있습니다.$[]: https://docs.mongodb.com/manual/reference/operator/update/positional-all/ #up.S [ ]

언급URL : https://stackoverflow.com/questions/15691224/mongoose-update-values-in-array-of-objects

반응형