In MongoDB, de $setUnion
aggregatiepijplijnoperator accepteert twee of meer arrays en retourneert een array met de elementen die in een van die invoerarrays voorkomen.
$setUnion
accepteert twee of meer argumenten, die allemaal elke geldige uitdrukking kunnen zijn, zolang ze elk in een array worden omgezet. $setUnion
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 $setUnion
. 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: { $setUnion: [ "$a", "$b" ] }
}
}
]
)
Resultaat:
{ "a" : [ 1, 2, 3 ], "b" : [ 1, 2, 3 ], "result" : [ 1, 2, 3 ] } { "a" : [ 1, 2, 3 ], "b" : [ 1, 2 ], "result" : [ 1, 2, 3 ] } { "a" : [ 1, 2 ], "b" : [ 1, 2, 3 ], "result" : [ 1, 2, 3 ] } { "a" : [ 1, 2, 3 ], "b" : [ 3, 4, 5 ], "result" : [ 1, 2, 3, 4, 5 ] } { "a" : [ 1, 2, 3 ], "b" : [ 4, 5, 6 ], "result" : [ 1, 2, 3, 4, 5, 6 ] }
Geneste arrays
De $setUnion
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 ] } { "_id" : 8, "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2, 3 ] ] } { "_id" : 9, "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2 ], 3 ] }
En we passen $setUnion
toe naar die twee documenten:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 6, 7, 8, 9 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setUnion: [ "$a", "$b" ] }
}
}
]
)
Resultaat:
{ "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2, 3 ] ], "result" : [ 1, 2, 3, [ 1, 2, 3 ] ] } { "a" : [ 1, 2, 3 ], "b" : [ [ 1, 2 ], 3 ], "result" : [ 1, 2, 3, [ 1, 2 ] ] } { "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2, 3 ] ], "result" : [ [ 1, 2, 3 ] ] } { "a" : [ [ 1, 2, 3 ] ], "b" : [ [ 1, 2 ], 3 ], "result" : [ 3, [ 1, 2 ], [ 1, 2, 3 ] ] }
Ontbrekende velden
$setUnion
toepassen naar een niet-bestaand veld resulteert in null
.
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 $setUnion
toepassen naar de a
en b
velden:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 10, 11, 12 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setUnion: [ "$a", "$b" ] }
}
}
]
)
Resultaat:
{ "a" : [ 1, 2, 3 ], "result" : null } { "b" : [ 1, 2, 3 ], "result" : null } { "result" : null }
Onjuist gegevenstype
Alle operanden van $setUnion
moeten arrays zijn. Als dat niet het geval is, wordt er een fout gegenereerd.
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 $setUnion
toe naar die documenten:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 13, 14, 15 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setUnion: [ "$a", "$b" ] }
}
}
]
)
Resultaat:
Error: command failed: { "ok" : 0, "errmsg" : "All operands of $setUnion must be arrays. One argument is of type: double", "code" : 17043, "codeName" : "Location17043" } : 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 $setUnion
operator filtert duplicaten uit het resultaat om een array uit te voeren die alleen unieke items bevat. Ook is de volgorde van de elementen in de uitvoerarray niet gespecificeerd.
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, 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 $setUnion
. toe operator voor hen:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 16, 17, 18, 19, 20, 21 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setUnion: [ "$a", "$b" ] }
}
}
]
)
Resultaat:
{ "a" : [ 1, 1, 2, 2, 3, 3 ], "b" : [ 1, 2, 3 ], "result" : [ 1, 2, 3 ] } { "a" : [ 1, 1, 2, 2, 3, 3 ], "b" : [ 1, 1, 2 ], "result" : [ 1, 2, 3 ] } { "a" : [ 1, 1, 2, 2, 3, 3 ], "b" : [ ], "result" : [ 1, 2, 3 ] } { "a" : [ 3, 2, 1, 2, 3, 1 ], "b" : [ 2, 3, 1 ], "result" : [ 1, 2, 3 ] } { "a" : [ 1, 3, 2, 2, 3, 1 ], "b" : [ 2, 1 ], "result" : [ 1, 2, 3 ] } { "a" : [ 2, 3, 1, 2, 3, 1 ], "b" : [ ], "result" : [ 1, 2, 3 ] }
Meer dan twee argumenten
Zoals vermeld, $setUnion
accepteert twee of meer argumenten. Alle voorgaande voorbeelden gebruikten twee argumenten. Hier is er een die drie argumenten gebruikt.
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 ] } { "_id" : 24, "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 4, 5 ] }
Deze documenten hebben een extra veld – een c
veld.
Laten we nu $setUnion
. toepassen naar die drie velden:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 22, 23, 24 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
c: 1,
result: { $setUnion: [ "$a", "$b", "$c" ] }
}
}
]
)
Resultaat:
{ "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 1, 2 ], "result" : [ 1, 2 ] } { "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 1, 2, 3 ], "result" : [ 1, 2, 3 ] } { "a" : [ 1, 2 ], "b" : [ 1, 2 ], "c" : [ 4, 5 ], "result" : [ 1, 2, 4, 5 ] }