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

MongoDB $push vs $addToSet :quelle est la différence ?

MongoDB a un $push opérateur et un $addToSet opérateur, qui font tous les deux une chose très similaire.

Les deux opérateurs ajoutent des valeurs à un tableau existant. La principale différence réside dans la façon dont ils traitent les tableaux qui contiennent déjà la valeur que vous essayez d'ajouter, ainsi que dans les modificateurs qui peuvent être utilisés.

Les différences

Valeurs existantes Si la valeur existe déjà dans le tableau, $push ajoutera toujours la valeur (entraînant des valeurs en double).
Cependant, $addToSet n'ajoute la valeur que si elle n'existe pas déjà dans le tableau. Par conséquent, si la valeur existe déjà, $addToSet ne l'ajoutera pas (il ne fera rien).
Modificateurs Le $push L'opérateur peut être utilisé avec des modificateurs supplémentaires, tels que $sort , $slice , et $position , alors que $addToSet ne peut pas (du moins, pas depuis MongoDB 4.4).

Valeurs existantes

Supposons que nous ayons une collection avec les documents suivants :

db.players.find()

Résultat :

{ "_id" : 1, "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
{ "_id" : 3, "scores" : [ 3, 5, 5 ] }

Utilisons $addToSet pour essayer d'ajouter une valeur à l'un des tableaux.

db.players.update(
   { _id: 3 },
   { $addToSet: { scores: 5 } }
)

Sortie :

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

Cela nous indique qu'il y avait un document correspondant (document 3), mais qu'il n'a pas été modifié. Il n'a pas été modifié car la valeur que nous avons essayé d'insérer (5 ) existe déjà dans le tableau.

Regardons dans la collection :

db.players.find()

Résultat :

{ "_id" : 1, "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
{ "_id" : 3, "scores" : [ 3, 5, 5 ] }

Comme prévu, le document 3 n'a pas été modifié.

Essayons $push à la place :

db.players.update(
   { _id: 3 },
   { $push: { scores: 5 } }
)

Sortie :

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Cette fois, nous voyons que le document a été modifié.

Nous pouvons le vérifier en vérifiant à nouveau la collection :

db.products.find()

Résultat :

{ "_id" : 1, "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
{ "_id" : 3, "scores" : [ 3, 5, 5, 5 ] }

Modificateurs

Le $push L'opérateur peut être utilisé avec des modificateurs tels que $position , $sort , et $slice .

Le $addToSet L'opérateur ne peut pas être utilisé avec ces modificateurs.

Voici ce qui se passe si j'essaie d'utiliser ces modificateurs avec $addToSet :

db.players.update(
   { _id: 3 },
   { 
     $addToSet: { 
        scores: {
           $each: [ 12 ],
           $position: 0,
           $sort: 1,
           $slice: 5
        }
      } 
    }
)

Sortie :

WriteResult({
	"nMatched" : 0,
	"nUpserted" : 0,
	"nModified" : 0,
	"writeError" : {
		"code" : 2,
		"errmsg" : "Found unexpected fields after $each in $addToSet: { $each: [ 12.0 ], $position: 0.0, $sort: 1.0, $slice: 5.0 }"
	}
})

Le message d'erreur nous indique que la $position , $sort , et $slice sont des champs inattendus (c'est-à-dire qu'ils ne devraient pas être là).

Essayons les mêmes modificateurs avec $push :

db.players.update(
   { _id: 3 },
   { 
     $push: { 
        scores: {
           $each: [ 12 ],
           $position: 0,
           $sort: 1,
           $slice: 5
        }
      } 
    }
)

Sortie :

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Cette fois, cela a fonctionné sans erreur.

Vérifiez le résultat :

db.players.find()

Résultat :

{ "_id" : 1, "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
{ "_id" : 3, "scores" : [ 3, 5, 5, 5, 12 ] }

Nous pouvons voir que la valeur a été ajoutée. Même si nous avons spécifié $position: 0 , nous avons également spécifié $sort: 1 , ce qui signifie que le tableau a été trié après que nous l'ayons positionné.

Nous avons également spécifié $slice: 5 , qui limitait le tableau à seulement 5 éléments (ce qui, en fin de compte, correspondait exactement au nombre d'éléments contenus dans le tableau de toute façon).