Definition
Takes two or more arrays and returns a single array containing the
unique elements that appear in any input array. $setUnion can be
used as an aggregation accumulator or an array operator.
Aggregation Accumulator
$setUnion is available as an accumulator in these stages:
Syntax
When used as an aggregation accumulator, $setUnion has the following
syntax:
{ $setUnion: "<array field>" }
Behavior
$setUnion performs set operation on arrays, treating arrays
as sets. If an array contains duplicate entries, $setUnion
ignores the duplicate entries. $setUnion ignores the order of
the elements.
$setUnion filters out duplicates in its result to output an
array that contains only unique entries. The order of the elements in
the output array is unspecified.
If a set contains a nested array element, $setUnion does not descend
into the nested array but evaluates the array at top-level.
Arguments that are null or resolve to null are included in the
results. Arguments that refer to a field that is missing are not
included in the results.
Example
Create a collection named sales with the following documents:
db.sales.insertMany( [ { _id: 1, items: [ "laptop", "tablet" ], location: "NYC" }, { _id: 2, items: [ "phone", "tablet" ], location: "NYC" }, { _id: 3, location: "NYC" }, { _id: 4, items: [ "desktop", { "accessories": [ "mouse", "keyboard"] } ], location: "NYC" } ] )
This example shows how you can use $setUnion as an accumulator. This
example accumulates all the unique elements in the items arrays when
grouping on the location field:
db.sales.aggregate( [ { $group: { _id: "$location", array: { "$setUnion": "$items" } } } ] )
The operation returns the following result:
[ { "_id": "NYC", "array": [ "laptop", "tablet", "phone", "desktop", { "accessories": [ "mouse", "keyboard"] } ] } ]
Array Operator
Syntax
When used as an array operator, $setUnion has the following syntax:
{ $setUnion: [ <expression1>, <expression2>, ... ] }
Behavior
$setUnion performs set operation on arrays, treating arrays
as sets. If an array contains duplicate entries, $setUnion
ignores the duplicate entries. $setUnion ignores the order of
the elements.
$setUnion filters out duplicates in its result to output an
array that contains only unique entries. The order of the elements in
the output array is unspecified.
The arguments can be any valid expression as long as they each resolve to an array. For more information on expressions, see Expressions.
If a set contains a nested array element, $setUnion does not descend
into the nested array but evaluates the array at top-level.
Example | Result | Notes | |||||
|---|---|---|---|---|---|---|---|
| | All elements from both arrays are combined and duplicate elements removed. | |||||
| | All elements from both arrays are combined and duplicate elements removed. | |||||
| | All elements from both arrays are combined and duplicate elements removed. | |||||
| | The result includes | |||||
| | The result consists of the unique elements in the second array because the first array is empty. | |||||
| | All elements from both arrays are combined and duplicate elements removed. |
Example
Consider an flowers collection with the following documents:
db.flowers.insertMany( [ { "_id" : 1, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ "rose", "orchid" ] }, { "_id" : 2, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ "orchid", "rose", "orchid" ] }, { "_id" : 3, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ "rose", "orchid", "jasmine" ] }, { "_id" : 4, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ "jasmine", "rose" ] }, { "_id" : 5, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ ] }, { "_id" : 6, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ [ "rose" ], [ "orchid" ] ] }, { "_id" : 7, "flowerFieldA" : [ "rose", "orchid" ], "flowerFieldB" : [ [ "rose", "orchid" ] ] }, { "_id" : 8, "flowerFieldA" : [ ], "flowerFieldB" : [ ] }, { "_id" : 9, "flowerFieldA" : [ ], "flowerFieldB" : [ "rose" ] } ] )
The following operation uses the $setUnion operator to
return an array of elements found in the flowerFieldA array or the
flowerFieldB array or both:
db.flowers.aggregate( [ { $project: { flowerFieldA:1, flowerFieldB: 1, allValues: { $setUnion: [ "$flowerFieldA", "$flowerFieldB" ] }, _id: 0 } } ] )
The operation returns the following results:
{ "flowerFieldA": [ "rose", "orchid" ], "flowerFieldB": [ "rose", "orchid" ], "allValues": [ "orchid", "rose" ] } { "flowerFieldA": [ "rose", "orchid" ], "flowerFieldB": [ "orchid", "rose", "orchid" ], "allValues": [ "orchid", "rose" ] } { "flowerFieldA": [ "rose", "orchid" ], "flowerFieldB": [ "rose", "orchid", "jasmine" ], "allValues": [ "orchid", "rose", "jasmine" ] } { "flowerFieldA": [ "rose", "orchid" ], "flowerFieldB": [ "jasmine", "rose" ], "allValues": [ "orchid", "rose", "jasmine" ] } { "flowerFieldA": [ "rose", "orchid" ], "flowerFieldB": [ ], "allValues": [ "orchid", "rose" ] } { "flowerFieldA": [ "rose", "orchid" ], "flowerFieldB": [ [ "rose" ], [ "orchid" ] ], "allValues": [ "orchid", "rose", [ "rose" ], [ "orchid" ] ] } { "flowerFieldA": [ "rose", "orchid" ], "flowerFieldB": [ [ "rose", "orchid" ] ], "allValues": [ "orchid", "rose", [ "rose", "orchid" ] ] } { "flowerFieldA": [ ], "flowerFieldB": [ ], "allValues": [ ] } { "flowerFieldA": [ ], "flowerFieldB": [ "rose" ], "allValues": [ "rose" ] }
Limitations
$setUniononly supports arrays and expressions that resolve to an array.$setUniondoes not guarantee the order of the elements in the output array.