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 dea
champ, et le troisième document n'a ni l'un ni l'autre.Voici ce qui se passe lorsque nous appliquons
$setEquals
aua
etb
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:1Comme 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:1Valeurs 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 retournertrue
. Sinon le résultat serafalse
.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 }