También puede probar el positional $
operador usado con findAndModify()
método. El operador identificará el elemento en una matriz para actualizar sin especificar explícitamente la posición del elemento en la matriz. Tenga en cuenta que el campo de matriz debe aparecer como parte del documento de consulta y para devolver el documento con las modificaciones realizadas en la actualización, use la nueva opción, por lo que su actualización sería como
db.tests.findAndModify({
query: {
"arr.cond": 4
},
update: {
"$set": {"arr.$.upd": 55 }
},
new : true,
fields: { "arr": 1, "_id": 0 }
})
producirá la salida:
{
"arr": [
{
"cond" : 1,
"upd" : 2
},
{
"cond" : 2,
"upd" : 3
},
{
"cond" : 4,
"upd" : 55
},
{
"cond" : 6,
"upd" : 7
},
{
"cond" : 8,
"upd" : 9
}
]
}
Ya que desea devolver el documento actualizado, con proyección posicional $ projection
El operador solo se puede usar en el documento de proyección del find()
método o findOne()
método por lo que el findAndModify()
field
de La opción no proyectará esa parte de la matriz usando $ projection
operador.
Una solución sería usar JavaScript nativo filter()
método en el campo arr devuelto 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);
Esto imprimirá
[ { "cond" : 4, "upd" : 55 } ]
-- ACTUALIZAR --
O el $elemMatch
proyección como sugirió en los comentarios a continuación:
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);
Salida :
{ "arr" : [ { "cond" : 4, "upd" : 55 } ] }