Du kan också prova positional $
operatorn som används med findAndModify()
metod. Operatören kommer att identifiera elementet i en array som ska uppdateras utan att explicit specificera elementets position i arrayen. Observera att matrisfältet måste visas som en del av frågedokumentet och för att returnera dokumentet med de ändringar som gjorts på uppdateringen, använd det nya alternativet, så att din uppdatering skulle se ut som
db.tests.findAndModify({
query: {
"arr.cond": 4
},
update: {
"$set": {"arr.$.upd": 55 }
},
new : true,
fields: { "arr": 1, "_id": 0 }
})
kommer att producera utdata:
{
"arr": [
{
"cond" : 1,
"upd" : 2
},
{
"cond" : 2,
"upd" : 3
},
{
"cond" : 4,
"upd" : 55
},
{
"cond" : 6,
"upd" : 7
},
{
"cond" : 8,
"upd" : 9
}
]
}
Eftersom du vill returnera det uppdaterade dokumentet, med projektion den positionella $-projektion
operatorn kan endast användas i projektionsdokumentet för find()
metoden eller findOne()
metoden så att fält
alternativet projicerar inte den delen av arrayen med $-projektion
operatör.
En lösning skulle vara att använda den inbyggda JavaScript-koden filter()
metod i det returnerade arr-fältet som
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);
Detta kommer att skrivas ut
[ { "cond" : 4, "upd" : 55 } ]
-- UPPDATERA --
Eller $elemMatch
projektion som du föreslog i kommentarerna nedan:
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);
Utdata :
{ "arr" : [ { "cond" : 4, "upd" : 55 } ] }