In MongoDB, de $setEquals
aggregatiepijplijnoperator vergelijkt twee of meer arrays en retourneert true
als ze dezelfde afzonderlijke elementen hebben en false
anders.
$setEquals
accepteert twee of meer argumenten, die allemaal elke geldige expressie kunnen zijn, zolang ze elk naar een array worden omgezet. $setEquals
behandelt de arrays als sets.
Voorbeeld
Stel dat we een verzameling hebben met de naam data
met de volgende documenten:
{ "_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 ] }
We kunnen de $setEquals
. toepassen operator tegen de a
en b
velden in die documenten.
Voorbeeld:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Resultaat:
{ "a" : [ 1, 2, 3 ], "b" : [ 1, 2, 3 ], "result" : true } { "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 ], "result" : false }
Geneste arrays
De $setEquals
operator daalt niet af in geneste arrays. Het evalueert alleen arrays op het hoogste niveau.
Stel dat onze collectie ook de volgende documenten bevat:
{ "_id" : 6, "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2, 3 ] ] } { "_id" : 7, "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2 ], 3 ] }
En we passen $setEquals
toe naar die twee documenten:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 6, 7 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Resultaat:
{ "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2, 3 ] ], "result" : false } { "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2 ], 3 ], "result" : false }
In het eerste document, de b
veld bevatte een array die slechts één element bevatte - een andere array. In dit geval is de buitenste array geëvalueerd en bleek deze niet dezelfde waarden te bevatten als in de array op a
.
Als de a
veld zelf een geneste array had bevat, was het misschien een ander verhaal geweest.
Stel dat we de volgende documenten hebben:
{ "_id" : 8, "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2, 3 ] ] } { "_id" : 9, "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2 ], 3 ] }
En we passen $setEquals
toe naar die documenten:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 8, 9 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Resultaat:
{ "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2, 3 ] ], "result" : true } { "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2 ], 3 ], "result" : false }
In het eerste document, a
komt overeen met b
precies, en dus is het resultaat true
.
In het tweede document, de geneste array op a
is anders dan de geneste array op b
, en dus krijgen we false
.
Ontbrekende velden
$setEquals
toepassen naar een niet-bestaand veld resulteert in een fout.
Bekijk de volgende documenten:
{ "_id" : 10, "a" : [ 1, 2, 3 ] } { "_id" : 11, "b" : [ 1, 2, 3 ] } { "_id" : 12 }
Het eerste document heeft geen b
veld, heeft het tweede document geen a
veld, en het derde document heeft geen van beide.
Dit is wat er gebeurt als we $setEquals
toepassen naar de a
en b
velden:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 10, 11, 12 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Resultaat:
Error: command failed: { "ok" : 0, "errmsg" : "All operands of $setEquals must be arrays. One argument is of type: missing", "code" : 17044, "codeName" : "Location17044" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:639:17 [email protected]/mongo/shell/assert.js:729:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1058:12 @(shell):1:1
Zoals het bericht aangeeft, moeten alle operanden arrays zijn. Een ontbrekend argument/veld is geen array.
Onjuist gegevenstype
Zoals te zien is in het vorige voorbeeld, zijn alle operanden van $setEquals
moeten arrays zijn. Als het veld waarnaar ze verwijzen ontbreekt, wordt een fout gegenereerd. Dezelfde fout treedt op wanneer de operand niet ontbreekt, maar gewoon van het verkeerde type is.
Stel dat onze collectie de volgende documenten bevat:
{ "_id" : 13, "a" : [ 1, 2, 3 ], "b" : 3 } { "_id" : 14, "a" : 3, "b" : [ 1, 2, 3 ] } { "_id" : 15, "a" : 2, "b" : 3 }
En we passen $setEquals
toe naar die documenten:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 13, 14, 15 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Resultaat:
Error: command failed: { "ok" : 0, "errmsg" : "All operands of $setEquals must be arrays. One argument is of type: double", "code" : 17044, "codeName" : "Location17044" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:639:17 [email protected]/mongo/shell/assert.js:729:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1058:12 @(shell):1:1
Dubbele waarden
De $setEquals
operator negeert dubbele vermeldingen. Het negeert ook de volgorde van de elementen.
Stel dat we de volgende documenten hebben:
{ "_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" : [ ] }
Dan passen we de $setEquals
. toe operator voor hen:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 16, 17, 18, 19, 20, 21 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setEquals: [ "$a", "$b" ] }
}
}
]
)
Resultaat:
{ "a" : [ 1, 1, 2, 2, 3, 3 ], "b" : [ 1, 2, 3 ], "result" : true } { "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" : [ ], "result" : false }
Meer dan twee argumenten
Zoals vermeld, $setEquals
accepteert twee of meer argumenten. In alle gevallen moeten de argumenten dezelfde afzonderlijke waarden hebben om true
te retourneren . Anders is het resultaat false
.
Stel dat we de volgende documenten hebben:
{ "_id" : 22, "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 1, 2 ] } { "_id" : 23, "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 1, 2, 3 ] }
Deze documenten hebben een extra veld – een c
veld.
Laten we nu $setEquals
toepassen naar die drie velden:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 22, 23 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
c: 1,
result: { $setEquals: [ "$a", "$b", "$c" ] }
}
}
]
)
Resultaat:
{ "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 1, 2 ], "result" : true } { "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 1, 2, 3 ], "result" : false }