I MongoDB, $setEquals
aggregeringspipeline-operatör jämför två eller flera arrayer och returnerar true
om de har samma distinkta element och false
annars.
$setEquals
accepterar två eller flera argument, som alla kan vara vilket giltigt uttryck så länge som var och en löser sig till en array. $setEquals
behandlar arrayerna som uppsättningar.
Exempel
Anta att vi har en samling som heter data
med följande dokument:
{ "_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 ] }
Vi kan använda $setEquals
operatorn mot a
och b
fält i dessa dokument.
Exempel:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Resultat:
{ "a" :[ 1, 2, 3 ], "b" :[ 1, 2, 3 ], "result" :sant }{ "a" :[ 1, 2, 3 ], "b" :[ 1, 2 ], "result" :false }{ "a" :[ 1, 2 ], "b" :[ 1, 2, 3 ], "result" :false }{ "a" :[ 1, 2, 3 ], "b" :[ 3, 4, 5 ], "result" :false }{ "a" :[ 1, 2, 3 ], "b" :[ 4, 5, 6 ], "resultat " :false }
Inkapslade arrayer
$setEquals
operatorn går inte ner i några kapslade arrayer. Den utvärderar bara arrayer på toppnivå.
Anta att vår samling också innehåller följande dokument:
{ "_id" :6, "a" :[ 1, 2, 3 ], "b" :[ [ 1, 2, 3 ] ] }{ "_id" :7, "a" :[ 1, 2, 3 ], "b" :[ [ 1, 2 ], 3 ] }
Och vi tillämpar $setEquals
till dessa två dokument:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 6, 7 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Resultat:
{ "a" :[ 1, 2, 3 ], "b" :[ [ 1, 2, 3 ] ], "result" :false }{ "a" :[ 1, 2, 3 ], " b" :[ [ 1, 2 ], 3 ], "result" :false }
I det första dokumentet, b
fältet innehöll en array som bara innehöll ett element – en annan array. I det här fallet utvärderades den yttre arrayen, och den visade sig inte innehålla samma värden som fanns i arrayen vid a
.
Men om a
fältet hade innehållit en kapslad array i sig, kan det ha varit en annan historia.
Anta att vi har följande dokument:
{ "_id" :8, "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2, 3 ] ] }{ "_id" :9, "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2 ], 3 ] }
Och vi tillämpar $setEquals
till dessa dokument:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 8, 9 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Resultat:
{ "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2, 3 ] ], "result" :sant }{ "a" :[ [ 1, 2, 3 ] ], "b" :[ [ 1, 2 ], 3 ], "result" :false }
I det första dokumentet, a
matchar b
exakt, och så resultatet är true
.
I det andra dokumentet, den kapslade arrayen vid a
skiljer sig från den kapslade arrayen vid b
, och så får vi false
.
Fält saknas
Använder $setEquals
till ett icke-existerande fält resulterar i ett fel.
Tänk på följande dokument:
{ "_id" :10, "a" :[ 1, 2, 3 ] }{ "_id" :11, "b" :[ 1, 2, 3 ] }{ "_id" :12 }Det första dokumentet har ingen
b
fältet har det andra dokumentet ingena
och det tredje dokumentet har inte heller.Det här är vad som händer när vi använder
$setEquals
tilla
ochb
fält:db.data.aggregate( [ { $match: { _id: { $in: [ 10, 11, 12 ] } } }, { $project: { _id: 0, a: 1, b: 1, result: { $setEquals: [ "$a", "$b" ] } } } ] )
Resultat:
Fel:kommando misslyckades:{ "ok" :0, "errmsg" :"Alla operander av $setEquals måste vara arrayer. Ett argument är av typen:saknas", "code" :17044, "codeName" :"Location17044 "} :aggregat misslyckades :[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@(skal):1:1Som meddelandet säger måste alla operander vara arrayer. Ett saknat argument/fält är inte en array.
Fel datatyp
Som sett i föregående exempel, alla operander av
$setEquals
måste vara arrayer. Om fältet de hänvisar till saknas, skapas ett fel. Samma fel uppstår när operanden inte saknas, utan helt enkelt är fel typ.Anta att vår samling innehåller följande dokument:
{ "_id" :13, "a" :[ 1, 2, 3 ], "b" :3 }{ "_id" :14, "a" :3, "b" :[ 1, 2, 3 ] }{ "_id" :15, "a" :2, "b" :3 }Och vi tillämpar
$setEquals
till dessa dokument:db.data.aggregate( [ { $match: { _id: { $in: [ 13, 14, 15 ] } } }, { $project: { _id: 0, a: 1, b: 1, result: { $setEquals: [ "$a", "$b" ] } } } ] )
Resultat:
Fel:kommando misslyckades:{ "ok" :0, "errmsg" :"Alla operander av $setEquals måste vara arrayer. Ett argument är av typen:double", "code" :17044, "codeName" :"Location17044 "} :aggregat misslyckades :[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@(skal):1:1Duplicera värden
$setEquals
Operatören ignorerar dubbla poster. Den ignorerar också ordningen på elementen.Anta att vi har följande dokument:
{ "_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" :[ ] }Sedan tillämpar vi
$setEquals
operatör till dem:db.data.aggregate( [ { $match: { _id: { $in: [ 16, 17, 18, 19, 20, 21 ] } } }, { $project: { _id: 0, a: 1, b: 1, result: { $setEquals: [ "$a", "$b" ] } } } ] )
Resultat:
{ "a" :[ 1, 1, 2, 2, 3, 3 ], "b" :[ 1, 2, 3 ], "result" :sant }{ "a" :[ 1, 1, 2, 2, 3, 3 ], "b" :[ 1, 2 ], "result" :false }{ "a" :[ 1, 1, 2, 2, 3, 3 ], "b" :[ ] , "result" :false }{ "a" :[ 3, 2, 1, 2, 3, 1 ], "b" :[ 2, 3, 1 ], "result" :true }{ "a" :[ 1, 3, 2, 2, 3, 1 ], "b" :[ 2, 1 ], "result" :false }{ "a" :[ 2, 3, 1, 2, 3, 1 ], "b " :[ ], "resultat" :falskt }Fler än två argument
Som nämnts,
$setEquals
accepterar två eller flera argument. I alla fall måste argumenten ha samma distinkta värden för att returneratrue
. Annars blir resultatetfalse
.Anta att vi har följande dokument:
{ "_id" :22, "a" :[ 1, 2 ], "b" :[ 1, 2 ], "c" :[ 1, 2 ] }{ "_id" :23, "a" :[ 1, 2 ], "b" :[ 1, 2 ], "c" :[ 1, 2, 3 ] }Dessa dokument har ett extra fält – ett
c
fältet.Låt oss nu tillämpa
$setEquals
till dessa tre fält:db.data.aggregate( [ { $match: { _id: { $in: [ 22, 23 ] } } }, { $project: { _id: 0, a: 1, b: 1, c: 1, result: { $setEquals: [ "$a", "$b", "$c" ] } } } ] )
Resultat:
{ "a" :[ 1, 2 ], "b" :[ 1, 2 ], "c" :[ 1, 2 ], "result" :sant }{ "a" :[ 1, 2 ] , "b" :[ 1, 2 ], "c" :[ 1, 2, 3 ], "result" :falskt }