Você também pode tentar o
positional $
operador usado com o findAndModify()
método. O operador identificará o elemento em uma matriz para atualizar sem especificar explicitamente a posição do elemento na matriz. Observe que o campo array deve aparecer como parte do documento de consulta e para retornar o documento com as modificações feitas na atualização, utilize a opção new, assim sua atualização ficaria assim db.tests.findAndModify({
query: {
"arr.cond": 4
},
update: {
"$set": {"arr.$.upd": 55 }
},
new : true,
fields: { "arr": 1, "_id": 0 }
})
produzirá a saída:
{
"arr": [
{
"cond" : 1,
"upd" : 2
},
{
"cond" : 2,
"upd" : 3
},
{
"cond" : 4,
"upd" : 55
},
{
"cond" : 6,
"upd" : 7
},
{
"cond" : 8,
"upd" : 9
}
]
}
Como você deseja retornar o documento atualizado, com projeção, o posicional
$ projection
operador só pode ser usado no documento de projeção do find()
ou o método findOne()
método para que o findAndModify()
field
de A opção não projetará essa parte da matriz usando o $ projection
operador. Uma solução alternativa seria usar o JavaScript nativo
filter()
método no campo arr retornado como 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);
Isso irá imprimir
[ { "cond" : 4, "upd" : 55 } ]
-- ATUALIZAÇÃO --
Ou o
$elemMatch
projeção como você sugeriu nos comentários abaixo: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);
Saída :
{ "arr" : [ { "cond" : 4, "upd" : 55 } ] }