Dans MongoDB, le db.collection.findAndModify()
La méthode modifie et renvoie un seul document.
La collection
part est le nom de la collection avec laquelle effectuer l'opération.
Exemple
Supposons que nous ayons une collection appelée pets
qui contient les documents suivants :
{ "_id" : 1, "name" : "Wag", "type" : "Dog" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Nous pouvons utiliser le db.collection.findAndModify()
méthode pour modifier un de ces documents.
db.pets.findAndModify({
query: { type: "Dog" },
update: { type: "Cow" }
})
Résultat :
{ "_id" : 1, "name" : "Wag", "type" : "Dog" }
Par défaut, il renvoie le document d'origine (pas la version modifiée).
Notez qu'un seul chien a été mis à jour, même s'il y a deux chiens dans la collection.
Vérifions la collection.
db.pets.find()
Résultat :
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Nous pouvons voir que le premier document contient maintenant une vache au lieu d'un chien. Cependant, nous pouvons également voir que le champ du nom du document a disparu.
En effet, lorsque vous transmettez un document à la update
argument, db.collection.findAndModify()
effectue un remplacement.
Utiliser un opérateur de mise à jour
Si nous voulions mettre à jour un champ, mais laisser le reste du document intact, nous aurions besoin d'inclure la ou les expressions d'opérateur de mise à jour pertinentes dans notre document.
Avec la collection dans son état actuel, effectuons un autre findAndModify()
opération contre lui, mais cette fois nous utiliserons le $set
opérateur de mise à jour pour définir uniquement le champ que nous voulons modifier.
db.pets.findAndModify({
query: { type: "Dog" },
update: { $set: { type: "Horse" } }
})
Résultat :
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
Cette fois, le chien restant a été mis à jour.
Jetons un coup d'œil à la collection.
db.pets.find()
Résultat :
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Cette fois, le champ correspondant a été mis à jour et le reste du document est resté intact.
Renvoyer le document modifié
Par défaut, le document d'origine est renvoyé lorsque vous utilisez db.collection.findAndModify()
.
Si vous préférez que le document modifié soit renvoyé à la place, utilisez le new
paramètre.
Par défaut, c'est new: false
, ce qui entraîne le renvoi du document d'origine. Mais en spécifiant new: true
entraîne le renvoi du document modifié à la place.
Faisons une autre modification, mais cette fois nous utiliserons new: true
.
db.pets.findAndModify({
query: { name: "Meow" },
update: { $set: { name: "Scratch" } },
new: true
})
Résultat :
{ "_id" : 3, "name" : "Scratch", "type" : "Cat" }
Nous avons donc renommé Meow
pour Scratch
et le résultat reflète nos modifications.
Mise à jour
Vous pouvez effectuer des upserts en spécifiant upsert: true
.
Un upsert est une option que vous pouvez utiliser sur les opérations de mise à jour. Si le document spécifié n'existe pas, un nouveau est inséré. Si c'est le cas existe, alors le document d'origine est mis à jour (et aucun document n'est inséré).
Exemple utilisant upsert: false
Voici un exemple de tentative de mise à jour d'un document inexistant lorsque upsert: false
.
db.pets.findAndModify({
query: { _id: 4 },
update: { _id: 4, name: "Fetch", type: "Dog" },
new: true
})
Résultat :
null
Le document n'existait pas dans la collection et donc findAndModify()
a renvoyé null
. Même si nous n'avons pas spécifié upsert: false
, nous savons que c'était faux parce que c'est la valeur par défaut (c'est-à-dire que c'est la valeur qui est utilisée lorsque vous ne spécifiez pas d'option upsert).
Si nous jetons un autre coup d'œil dans la collection, nous pouvons voir que le document n'a pas été mis à jour.
db.pets.find()
Résultat :
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Scratch", "type" : "Cat" }
Exemple utilisant upsert: true
Maintenant, c'est à nouveau, mais cette fois nous spécifions upsert: true
.
db.pets.findAndModify({
query: { _id: 4 },
update: { _id: 4, name: "Fetch", type: "Dog" },
new: true,
upsert: true
})
Résultat :
{ "_id" : 4, "name" : "Fetch", "type" : "Dog" }
Cette fois, un nouveau document est mis à jour et nous voyons le document mis à jour comme sortie (car nous avons spécifié new: true
).
Vérifions à nouveau la collection.
db.pets.find()
Résultat :
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Scratch", "type" : "Cat" } { "_id" : 4, "name" : "Fetch", "type" : "Dog" }
Nous pouvons donc voir que le nouveau document a bien été mis à jour.
Le paramètre arrayFilters
Lorsque vous travaillez avec des tableaux, vous pouvez utiliser les arrayFilters
paramètre avec la position $
opérateur pour déterminer les éléments du tableau à mettre à jour. Cela vous permet de mettre à jour un élément de tableau en fonction de sa valeur, même si vous ne connaissez pas sa position.
Par exemple, supposons que nous ayons une collection appelée players
avec les documents suivants :
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 15, 11, 8 ] }
Nous pourrions exécuter la requête suivante pour mettre à jour uniquement les éléments du tableau dont la valeur est supérieure à un certain montant (dans ce cas, 10).
db.players.findAndModify({
query: { scores: { $gte: 10 } },
update: { $set: { "scores.$[e]" : 10 } },
arrayFilters: [ { "e": { $gte: 10 } } ]
})
Résultat :
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
Comme prévu, cela ne met à jour qu'un seul document, même si deux documents correspondent aux critères.
Voici à quoi ressemblent les documents maintenant.
db.players.find()
Résultat :
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 10, 10 ] } { "_id" : 3, "scores" : [ 15, 11, 8 ] }
Le document 2 avait deux éléments de tableau mis à jour, car ces éléments correspondaient aux critères.
Plus d'informations
Le db.collection.findAndModify()
La méthode accepte également d'autres paramètres, tels que writeConcern
, collation
, bypassDocumentValidation
et plus encore.
Voir la documentation MongoDB pour db.collections.findAndModify()
pour plus d'informations.