Czy istnieje sposób na aktualizację wartości w obiekcie?
{
_id: 1,
name: 'John Smith',
items: [{
id: 1,
name: 'item 1',
value: 'one'
},{
id: 2,
name: 'item 2',
value: 'two'
}]
}
Powiedzmy, że chcę zaktualizować nazwy i wartości dla pozycji, gdzie id = 2;
Próbowałem następujących rzeczy w / mangusta:
var update = {name: 'updated item2', value: 'two updated'};
Person.update({'items.id': 2}, {'$set': {'items.$': update}}, function(err) { ...
Problem z tym podejściem polega na tym, że aktualizuje / ustawia cały obiekt, dlatego w tym przypadku tracę pole id.
Czy istnieje lepszy sposób w mongoose na ustawienie pewnych wartości w tablicy, ale pozostawienie innych wartości w spokoju?
Zapytałem również tylko o osobę:
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().
});
items.$.name
miałeśitems.users.$.status
? czy to zadziała?model.update({"_id": 1, "items.id": "2"}, {$set: {"items.$.name": "yourValue","items.$.value": "yourvalue"}})
Dokument Mongodb
źródło
Jest na to sposób mangusty.
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') });
źródło
Dla każdego dokumentu operator aktualizacji
$set
może ustawić wiele wartości , więc zamiast zastępować cały obiekt witems
tablicy, można ustawić polaname
ivalue
obiektu indywidualnie.{'$set': {'items.$.name': update.name , 'items.$.value': update.value}}
źródło
Jest jedna rzecz do zapamiętania, gdy szukasz obiektu w tablicy na podstawie więcej niż jednego warunku, użyj $ elemMatch
Person.update( { _id: 5, grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } } }, { $set: { "grades.$.std" : 6 } } )
tutaj jest dokumentacja
źródło
Poniżej znajduje się przykład bardziej dynamicznego aktualizowania wartości w tablicy obiektów.
Person.findOneAndUpdate({_id: id}, { "$set": {[`items.$[outer].${propertyName}`]: value} }, { "arrayFilters": [{ "outer.id": itemId }] }, function(err, response) { ... })
Zauważ, że robiąc to w ten sposób, byłbyś w stanie zaktualizować jeszcze głębsze poziomy zagnieżdżonej tablicy, dodając dodatkowy
arrayFilters
operator pozycyjny, taki jak ten:"$set": {[`items.$[outer].innerItems.$[inner].${propertyName}`]: value} "arrayFilters":[{ "outer.id": itemId },{ "inner.id": innerItemId }]
Więcej zastosowań można znaleźć w oficjalnych dokumentach .
źródło
update( {_id: 1, 'items.id': 2}, {'$set': {'items.$[]': update}}, {new: true})
Oto dokument o
$[]
: https://docs.mongodb.com/manual/reference/operator/update/positional-all/#up. S []źródło
W mongoose możemy aktualizować, jak prosta tablica
user.updateInfoByIndex(0,"test") User.methods.updateInfoByIndex = function(index, info) ={ this.arrayField[index]=info this.save() }
źródło
W Mongoose możemy zaktualizować wartość tablicy za pomocą
$set
notacji inside dot (.
) do określonej wartości w następujący sposóbdb.collection.update({"_id": args._id, "viewData._id": widgetId}, {$set: {"viewData.$.widgetData": widgetDoc.widgetData}})
źródło
Wypróbowałem inne rozwiązania, które działały dobrze, ale pułapka ich odpowiedzi polega na tym, że tylko pola już istniejące będą aktualizować, dodając upsert, nic nie da, więc wymyśliłem to.
Person.update({'items.id': 2}, {$set: { 'items': { "item1", "item2", "item3", "item4" } }, {upsert: true })
źródło
Miałem podobne problemy. Oto najczystszy sposób na zrobienie tego.
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(); });
źródło