MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Comment récupérer la nouvelle valeur après une mise à jour dans un tableau embarqué ?

Si vous êtes sur MongoDB 3.0 ou plus récent, vous devez utiliser le .findOneAndUpdate() et utilisez la projection option pour spécifier le sous-ensemble de champs à renvoyer. Vous devez également définir returnNewDocument à true . Bien sûr, vous devez utiliser le $elemMatch opérateur de projection ici car vous ne pouvez pas utiliser une projection positionnelle et renvoyer le nouveau document.

Comme quelqu'un l'a souligné :

Vous devriez utiliser .findOneAndUpdate() car .findAndModify() est mis en évidence comme obsolète dans chaque pilote de langue officielle. L'autre chose est que la syntaxe et les options sont assez cohérentes entre les pilotes pour .findOneAndUpdate() . Avec .findAndModify() , la plupart des pilotes n'utilisent pas le même objet unique avec les clés "query/update/fields". C'est donc un peu moins déroutant quand quelqu'un s'applique à une autre langue pour être cohérent. Modifications de l'API standardisées pour .findOneAndUpdate() correspondent en fait à la version 3.x du serveur plutôt qu'à la version 3.2.x. La distinction complète étant que les méthodes shell étaient en fait à la traîne des autres pilotes (pour une fois !) dans l'implémentation de la méthode. Ainsi, la plupart des pilotes avaient en fait une bosse de version majeure correspondant à la version 3.x avec de tels changements.

db.collection.findOneAndUpdate( 
    { 
        "_id": ObjectId("56d6a7292c06e85687f44541"), 
         "rankings._id" : ObjectId("46d6a7292c06e85687f55543") 
    },  
    { $inc : { "rankings.$.score" : 1 } },  
    { 
        "projection": { 
            "rankings": { 
                "$elemMatch": { "_id" : ObjectId("46d6a7292c06e85687f55543") } 
            }
        }, 
        "returnNewDocument": true 
    }
)

À partir de MongoDB 3.0, vous devez utiliser findAndModify et les fields options vous devez également définir new à true dans autre pour renvoyer la nouvelle valeur.

db.collection.findAndModify({   
    query: { 
        "_id": ObjectId("56d6a7292c06e85687f44541"), 
        "rankings._id" : ObjectId("46d6a7292c06e85687f55543") 
    },     
    update: { $inc : { "rankings.$.score" : 1 } },       
    new: true,  
    fields: { 
        "rankings": { 
            "$elemMatch": { "_id" : ObjectId("46d6a7292c06e85687f55543") }
        }  
    }
})

Les deux requêtes donnent :

{
        "_id" : ObjectId("56d6a7292c06e85687f44541"),
        "rankings" : [
                {
                        "_id" : ObjectId("46d6a7292c06e85687f55543"),
                        "name" : "Ranking 2",
                        "score" : 11
                }
        ]
}