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

MongoDB $setUnion

Dans MongoDB, le $setUnion L'opérateur de pipeline d'agrégation accepte deux tableaux ou plus et renvoie un tableau contenant les éléments qui apparaissent dans l'un de ces tableaux d'entrée.

$setUnion accepte deux ou plusieurs arguments, qui peuvent tous être n'importe quelle expression valide tant qu'ils se résolvent chacun en un tableau. $setUnion 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 $setUnion 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: { $setUnion: [ "$a", "$b" ] }
          }
     }
   ]
) 

Résultat :

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

Tableaux imbriqués

Le $setUnion 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 ] }{ "_id" :8, "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2, 3 ] ] }{ "_id" :9, "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2 ], 3 ] }

Et nous appliquons $setUnion à ces deux documents :

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

Résultat :

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

Champs manquants

Application de $setUnion à un champ inexistant donne null .

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 $setUnion au a et b champs :

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

Résultat :

{ "a" :[ 1, 2, 3 ], "result" :null }{ "b" :[ 1, 2, 3 ], "result" :null }{ "result" :null } 

Type de données incorrect

Tous les opérandes de $setUnion doivent être des tableaux. Si ce n'est pas le cas, une erreur est générée.

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 $setUnion à ces documents :

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

Résultat :

Erreur :la commande a échoué :{ "ok" :0, "errmsg" :"Tous les opérandes de $setUnion doivent être des tableaux. Un argument est de type :double", "code" :17043, "codeName" :"Location17043 "} :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 $setUnion L'opérateur filtre les doublons dans son résultat pour générer un tableau contenant uniquement des entrées uniques. De plus, l'ordre des éléments dans le tableau de sortie n'est pas spécifié.

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, 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 $setUnion opérateur pour eux :

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

Résultat :

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

Plus de deux arguments

Comme mentionné, $setUnion accepte deux arguments ou plus. Tous les exemples précédents utilisaient deux arguments. En voici une qui utilise trois arguments.

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 ] }{ "_id" :24, "a" :[ 1, 2 ], "b" :[ 1, 2 ], "c" :[ 4, 5 ] }

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

Maintenant, appliquons $setUnion à ces trois champs :

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

Résultat :

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