Puoi anche provare il positional $
operatore utilizzato con findAndModify()
metodo. L'operatore identificherà l'elemento in una matrice da aggiornare senza specificare esplicitamente la posizione dell'elemento nella matrice. Nota, il campo dell'array deve apparire come parte del documento di query e per restituire il documento con le modifiche apportate all'aggiornamento, usa la nuova opzione, in modo che il tuo aggiornamento sia come
db.tests.findAndModify({
query: {
"arr.cond": 4
},
update: {
"$set": {"arr.$.upd": 55 }
},
new : true,
fields: { "arr": 1, "_id": 0 }
})
produrrà l'output:
{
"arr": [
{
"cond" : 1,
"upd" : 2
},
{
"cond" : 2,
"upd" : 3
},
{
"cond" : 4,
"upd" : 55
},
{
"cond" : 6,
"upd" : 7
},
{
"cond" : 8,
"upd" : 9
}
]
}
Poiché si desidera restituire il documento aggiornato, con proiezione il posizionale $ projection
può essere utilizzato solo nel documento di proiezione di find()
o il metodo findOne()
metodo quindi il findAndModify()
' field
l'opzione non proietterà quella parte dell'array utilizzando $ projection
operatore.
Una soluzione alternativa sarebbe utilizzare il JavaScript nativo filter()
metodo sul campo arr restituito come
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);
Questo verrà stampato
[ { "cond" : 4, "upd" : 55 } ]
-- AGGIORNAMENTO --
Oppure il $elemMatch
proiezione come hai suggerito nei commenti qui sotto:
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);
Risultato :
{ "arr" : [ { "cond" : 4, "upd" : 55 } ] }