Vous pouvez également essayer le positional $
opérateur utilisé avec findAndModify()
méthode. L'opérateur identifiera l'élément dans un tableau à mettre à jour sans spécifier explicitement la position de l'élément dans le tableau. Notez que le champ de tableau doit apparaître dans le cadre du document de requête et pour renvoyer le document avec les modifications apportées à la mise à jour, utilisez la nouvelle option, de sorte que votre mise à jour ressemblerait à
db.tests.findAndModify({
query: {
"arr.cond": 4
},
update: {
"$set": {"arr.$.upd": 55 }
},
new : true,
fields: { "arr": 1, "_id": 0 }
})
produira la sortie :
{
"arr": [
{
"cond" : 1,
"upd" : 2
},
{
"cond" : 2,
"upd" : 3
},
{
"cond" : 4,
"upd" : 55
},
{
"cond" : 6,
"upd" : 7
},
{
"cond" : 8,
"upd" : 9
}
]
}
Puisque vous voulez retourner le document mis à jour, avec projection le positionnel $ projection
l'opérateur ne peut être utilisé que dans le document de projection de find()
ou la méthode findOne()
méthode de sorte que le findAndModify()
field
de l'option ne projettera pas cette partie du tableau en utilisant $ projection
opérateur.
Une solution de contournement serait d'utiliser le JavaScript natif filter()
méthode sur le champ arr retourné comme
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);
Cela imprimera
[ { "cond" : 4, "upd" : 55 } ]
-- MISE À JOUR --
Ou le $elemMatch
projection comme vous l'avez suggéré dans les commentaires ci-dessous :
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);
Sortie :
{ "arr" : [ { "cond" : 4, "upd" : 55 } ] }