Можете също да опитате positional $
оператор, използван с findAndModify()
метод. Операторът ще идентифицира елемента в масива за актуализиране, без изрично да указва позицията на елемента в масива. Имайте предвид, че полето за масив трябва да се появи като част от документа на заявката и за да върнете документа с промените, направени при актуализацията, използвайте новата опция, така че актуализацията ви ще бъде като
db.tests.findAndModify({
query: {
"arr.cond": 4
},
update: {
"$set": {"arr.$.upd": 55 }
},
new : true,
fields: { "arr": 1, "_id": 0 }
})
ще произведе резултата:
{
"arr": [
{
"cond" : 1,
"upd" : 2
},
{
"cond" : 2,
"upd" : 3
},
{
"cond" : 4,
"upd" : 55
},
{
"cond" : 6,
"upd" : 7
},
{
"cond" : 8,
"upd" : 9
}
]
}
Тъй като искате да върнете актуализирания документ, с проекция на позиционния $ projection
може да се използва само в документа за проекция на find()
метод или findOne()
метод, така че findAndModify()
field
на опцията няма да проектира тази част от масива с помощта на $ projection
оператор.
Заобиколно решение би било да се използва собственият JavaScript filter()
метод на върнатото поле arr като
var result = db.tests.findAndModify({
query: {
"arr.cond": 4
},
update: {
"$set": {"arr.$.upd": 55 }
},
new : true,
fields: { "arr": 1, "_id": 0 }
})
var updated = []
if (result && result.arr) updated = result.arr.filter(function (item) { return item.cond == 4; });
printjson(updated);
Това ще отпечата
[ { "cond" : 4, "upd" : 55 } ]
-- АКТУАЛИЗАЦИЯ --
Или $elemMatch
проекция, както предложихте в коментарите по-долу:
var result = db.tests.findAndModify({
query: {
"arr.cond": 4
},
update: {
"$set": {"arr.$.upd": 55 }
},
new : true,
fields: {"arr": {"$elemMatch": { "cond": 4 } }, "_id": 0 }
})
printjson(result);
Изход :
{ "arr" : [ { "cond" : 4, "upd" : 55 } ] }