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

MongoDB $setEquals

Dans MongoDB, le $setEquals l'opérateur de pipeline d'agrégation compare deux tableaux ou plus et renvoie true s'ils ont les mêmes éléments distincts et false sinon.

$setEquals accepte deux arguments ou plus, qui peuvent tous être n'importe quelle expression valide tant qu'ils se résolvent chacun en un tableau. $setEquals traite les tableaux comme des ensembles.

Exemple

Supposons que nous ayons une collection appelée data avec les documents suivants :

{ "_id" :1, "a" :[ 1, 2, 3 ], "b" :[ 1, 2, 3 ] }{ "_id" :2, "a" :[ 1, 2, 3 ], "b" :[ 1, 2 ] }{ "_id" :3, "a" :[ 1, 2 ], "b" :[ 1, 2, 3 ] }{ "_id" :4, " a" :[ 1, 2, 3 ], "b" :[ 3, 4, 5 ] }{ "_id" :5, "a" :[ 1, 2, 3 ], "b" :[ 4, 5 , 6 ] }

Nous pouvons appliquer le $setEquals opérateur contre le a et b champs dans ces documents.

Exemple :

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setEquals: [ "$a", "$b" ] }
          }
     }
   ]
) 

Résultat :

{ "a" :[ 1, 2, 3 ], "b" :[ 1, 2, 3 ], "résultat" :vrai }{ "a" :[ 1, 2, 3 ], "b" :[ 1, 2 ], "résultat" :faux }{ "a" :[ 1, 2 ], "b" :[ 1, 2, 3 ], "résultat" :faux }{ "a" :[ 1, 2, 3 ], "b" :[ 3, 4, 5 ], "résultat" :faux }{ "a" :[ 1, 2, 3 ], "b" :[ 4, 5, 6 ], "résultat " :faux }

Tableaux imbriqués

Le $setEquals L'opérateur ne descend dans aucun tableau imbriqué. Il évalue uniquement les tableaux de niveau supérieur.

Supposons que notre collection contienne également les documents suivants :

{ "_id" :6, "a" :[ 1, 2, 3 ], "b" :[ [ 1, 2, 3 ] ] }{ "_id" :7, "a" :[ 1, 2, 3 ], "b" :[ [ 1, 2 ], 3 ] }

Et nous appliquons $setEquals à ces deux documents :

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 6, 7 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setEquals: [ "$a", "$b" ] }
          }
     }
   ]
) 

Résultat :

{ "a" :[ 1, 2, 3 ], "b" :[ [ 1, 2, 3 ] ], "résultat" :faux }{ "a" :[ 1, 2, 3 ], " b" :[ [ 1, 2 ], 3 ], "résultat" :faux }

Dans le premier document, le b champ contenait un tableau qui ne contenait qu'un seul élément - un autre tableau. Dans ce cas, le tableau externe a été évalué et il s'est avéré qu'il ne contenait pas les mêmes valeurs que celles qui se trouvaient dans le tableau à a .

Cependant, si le a champ contenait lui-même un tableau imbriqué, cela aurait pu être une autre histoire.

Supposons que nous ayons les documents suivants :

{ "_id" :8, "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2, 3 ] ] }{ "_id" :9, "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2 ], 3 ] }

Et nous appliquons $setEquals à ces documents :

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 8, 9 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setEquals: [ "$a", "$b" ] }
          }
     }
   ]
) 

Résultat :

{ "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2, 3 ] ], "résultat" :vrai }{ "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2 ], 3 ], "résultat" :faux }

Dans le premier document, a correspond à b exactement, et donc le résultat est true .

Dans le deuxième document, le tableau imbriqué à a est différent du tableau imbriqué à b , et nous obtenons donc false .

Champs manquants

Application de $setEquals à un champ inexistant entraîne une erreur.

Considérez les documents suivants :

{ "_id" :10, "a" :[ 1, 2, 3 ] }{ "_id" :11, "b" :[ 1, 2, 3 ] }{ "_id" :12 } 

Le premier document n'a pas de b champ, le deuxième document n'a pas de a champ, et le troisième document n'a ni l'un ni l'autre.

Voici ce qui se passe lorsque nous appliquons $setEquals au a et b champs :

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 10, 11, 12 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setEquals: [ "$a", "$b" ] }
          }
     }
   ]
) 

Résultat :

Erreur :la commande a échoué :{ "ok" :0, "errmsg" :"Tous les opérandes de $setEquals doivent être des tableaux. Un argument est de type :missing", "code" :17044, "codeName" :"Location17044 "} :l'agrégat a échoué :[email protected]/mongo/shell/utils.js:25:[email protected]/mongo/shell/assert.js:18:[email protected]/mongo/shell/assert. js:639:[email protected]/mongo/shell/assert.js:729:[email protected]/mongo/shell/db.js:266:[email protected]/mongo/shell/collection.js :1058:12@(shell):1:1

Comme l'indique le message, tous les opérandes doivent être des tableaux. Un argument/champ manquant n'est pas un tableau.

Type de données incorrect

Comme vu dans l'exemple précédent, tous les opérandes de $setEquals doivent être des tableaux. Si le champ auquel ils se réfèrent est manquant, une erreur est renvoyée. La même erreur se produit lorsque l'opérande n'est pas manquant, mais qu'il est simplement du mauvais type.

Supposons que notre collection contienne les documents suivants :

{ "_id" :13, "a" :[ 1, 2, 3 ], "b" :3 }{ "_id" :14, "a" :3, "b" :[ 1, 2, 3 ] }{ "_id" :15, "a" :2, "b" :3 }

Et nous appliquons $setEquals à ces documents :

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 13, 14, 15 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setEquals: [ "$a", "$b" ] }
          }
     }
   ]
) 

Résultat :

Erreur :la commande a échoué :{ "ok" :0, "errmsg" :"Tous les opérandes de $setEquals doivent être des tableaux. Un argument est de type :double", "code" :17044, "codeName" :"Location17044 "} :l'agrégat a échoué :[email protected]/mongo/shell/utils.js:25:[email protected]/mongo/shell/assert.js:18:[email protected]/mongo/shell/assert. js:639:[email protected]/mongo/shell/assert.js:729:[email protected]/mongo/shell/db.js:266:[email protected]/mongo/shell/collection.js :1058:12@(shell):1:1

Valeurs en double

Le $setEquals l'opérateur ignore les entrées en double. Il ignore également l'ordre des éléments.

Supposons que nous ayons les documents suivants :

{ "_id" :16, "a" :[ 1, 1, 2, 2, 3, 3 ], "b" :[ 1, 2, 3 ] }{ "_id" :17, "a" :[ 1, 1, 2, 2, 3, 3 ], "b" :[ 1, 2 ] }{ "_id" :18, "a" :[ 1, 1, 2, 2, 3, 3 ], "b" :[ ] }{ "_id" :19, "a" :[ 3, 2, 1, 2, 3, 1 ], "b" :[ 2, 3, 1 ] }{ "_id" :20 , "a" :[ 1, 3, 2, 2, 3, 1 ], "b" :[ 2, 1 ] }{ "_id" :21, "a" :[ 2, 3, 1, 2, 3 , 1 ], "b" :[ ] }

Ensuite, nous appliquons le $setEquals opérateur pour eux :

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 16, 17, 18, 19, 20, 21 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $setEquals: [ "$a", "$b" ] }
          }
     }
   ]
) 

Résultat :

{ "a" :[ 1, 1, 2, 2, 3, 3 ], "b" :[ 1, 2, 3 ], "result" :vrai }{ "a" :[ 1, 1, 2, 2, 3, 3 ], "b" :[ 1, 2 ], "résultat" :faux }{ "a" :[ 1, 1, 2, 2, 3, 3 ], "b" :[ ] , "résultat" :faux }{ "a" :[ 3, 2, 1, 2, 3, 1 ], "b" :[ 2, 3, 1 ], "résultat" :vrai }{ "a" :[ 1, 3, 2, 2, 3, 1 ], "b" :[ 2, 1 ], "résultat" :faux }{ "a" :[ 2, 3, 1, 2, 3, 1 ], "b " :[ ], "résultat" :faux }

Plus de deux arguments

Comme mentionné, $setEquals accepte deux arguments ou plus. Dans tous les cas, les arguments doivent avoir les mêmes valeurs distinctes pour retourner true . Sinon le résultat sera false .

Supposons que nous ayons les documents suivants :

{ "_id" :22, "a" :[ 1, 2 ], "b" :[ 1, 2 ], "c" :[ 1, 2 ] }{ "_id" :23, "a" :[ 1, 2 ], "b" :[ 1, 2 ], "c" :[ 1, 2, 3 ] }

Ces documents ont un champ supplémentaire - un c champ.

Maintenant, appliquons $setEquals à ces trois champs :

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 22, 23 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            c: 1,
            result: { $setEquals: [ "$a", "$b", "$c" ] }
          }
     }
   ]
) 

Résultat :

{ "a" :[ 1, 2 ], "b" :[ 1, 2 ], "c" :[ 1, 2 ], "résultat" :vrai }{ "a" :[ 1, 2 ] , "b" :[ 1, 2 ], "c" :[ 1, 2, 3 ], "résultat" :faux }