Dans MongoDB, le $setIntersection
L'opérateur de pipeline d'agrégation accepte deux tableaux ou plus et renvoie un tableau contenant les éléments qui apparaissent dans tous les tableaux d'entrée.
$setIntersection
accepte deux arguments ou plus, qui peuvent tous être n'importe quelle expression valide tant qu'ils se résolvent chacun en un tableau. $setIntersection
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 $setIntersection
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: { $setIntersection: [ "$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 ] }{ "a" :[ 1, 2 ], "b" :[ 1, 2, 3 ], "résultat" :[ 1, 2 ] }{ "a" :[ 1, 2, 3 ], "b" :[ 3, 4, 5 ], "résultat" :[ 3 ] }{ "a" :[ 1, 2, 3 ], "b" :[ 4, 5, 6 ], "résultat" :[ ] }
Tableaux imbriqués
Le $setIntersection
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 $setIntersection
à ces deux documents :
db.data.aggregate(
[
{ $match: { _id: { $in: [ 6, 7 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setIntersection: [ "$a", "$b" ] }
}
}
]
)
Résultat :
{ "a" :[ 1, 2, 3 ], "b" :[ [ 1, 2, 3 ] ], "résultat" :[ ] }{ "a" :[ 1, 2, 3 ], "b" :[ [ 1, 2 ], 3 ], "résultat" :[ 3 ] }
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é pas contenir l'une des valeurs qui se trouvaient dans le tableau à a
.
Cependant, 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 ] }
Le document 8 contient un tableau imbriqué à la fois au a
et b
champs, et les deux tableaux sont identiques.
Voici ce qui se passe lorsque nous appliquons $setIntersection
à ces documents :
db.data.aggregate(
[
{ $match: { _id: { $in: [ 8, 9 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setIntersection: [ "$a", "$b" ] }
}
}
]
)
Résultat :
{ "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2, 3 ] ], "résultat" :[ [ 1, 2, 3 ] ] }{ "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2 ], 3 ], "résultat" :[ ] }
Dans le premier document, a
correspond à b
exactement, et donc le résultat est un tableau identique (un tableau externe contenant le tableau interne).
Dans le second document, le contenu de a
ne correspond à aucun des contenus de b
, et donc un tableau vide est renvoyé.
Champs manquants
Application de $setIntersection
à 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 dea
champ, et le troisième document n'a ni l'un ni l'autre.Voici ce qui se passe lorsque nous appliquons
$setIntersection
aua
etb
champs :db.data.aggregate( [ { $match: { _id: { $in: [ 10, 11, 12 ] } } }, { $project: { _id: 0, a: 1, b: 1, result: { $setIntersection: [ "$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
$setIntersection
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
$setIntersection
à ces documents :db.data.aggregate( [ { $match: { _id: { $in: [ 13, 14, 15 ] } } }, { $project: { _id: 0, a: 1, b: 1, result: { $setIntersection: [ "$a", "$b" ] } } } ] )
Résultat :
Erreur :la commande a échoué :{ "ok" :0, "errmsg" :"Tous les opérandes de $setIntersection doivent être des tableaux. Un argument est de type :double", "code" :17047, "codeName" :"Location17047 "} :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:1Valeurs en double
Le
$setIntersection
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, 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
$setIntersection
opérateur pour eux :db.data.aggregate( [ { $match: { _id: { $in: [ 16, 17, 18, 19, 20, 21 ] } } }, { $project: { _id: 0, a: 1, b: 1, result: { $setIntersection: [ "$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, 2 ], "résultat" :[ 1, 2 ] }{ "a" :[ 1, 1, 2, 2, 3 , 3 ], "b" :[ ], "résultat" :[ ] }{ "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 ] } { "a" :[ 2, 3, 1, 2, 3, 1 ], "b" :[ ], "résultat" :[ ] }Plus de deux arguments
Comme mentionné,
$setIntersection
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 ] }Ces documents ont un champ supplémentaire - un
c
champ.Maintenant, appliquons
$setIntersection
à ces trois champs :db.data.aggregate( [ { $match: { _id: { $in: [ 22, 23 ] } } }, { $project: { _id: 0, a: 1, b: 1, c: 1, result: { $setIntersection: [ "$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 ] }