I have documents in a collection as follows :
{ _id : 1 , data : [7,4,0] }
{ _id : 2 , data : [4,5,6] }
{ _id : 3 , data : [6,7,8] }
I want to union the data
array from two or more documents.
The query I am using to find the union of data
array of id
1 and 2 is:
db.coll.aggregate(
{
$match : {
_id: { $in: [1, 2] }
}
},
{
$group: {
_id: 0,
s0: { $first: "$data"},
s1: { $first: "$data"}
}
},
{
$project: {
_id: 0,
ans: { $setUnion: [ "$s0","$s1"]}
}
}
).pretty()
But the query results in:
{7, 5, 0}
which seems to be the data of id
1 only.
How to achieve the union between two or more documents on same array field?
PS: I'm using MongoDB 3.4
You can use $unwind
and $group
with $addToSet
,
$match
your conditions$unwind
deconstruct data
array$group
by null and do $addToSet
to get unique numbers form data
db.coll.aggregate([
{ $match: { _id: { $in: [1, 2] } } },
{ $unwind: "$data" },
{
$group: {
_id: null,
data: { $addToSet: "$data" }
}
}
]).pretty()
Playground
For a more efficient query, use the $reduce
operator to flatten the arrays. This will allow you to concat any number of arrays, so instead of just doing a union of the two arrays from docs 1 and 2, this will also apply for other arrays as well.
Consider running the following aggregate operation:
db.coll.aggregate([
{ "$match": { "_id": { "$in": [1, 2] } } },
{
"$group": {
"_id": 0,
"data": { "$push": "$data" }
}
},
{
"$project": {
"data": {
"$reduce": {
"input": "$data",
"initialValue": [],
"in": { "$setUnion": ["$$value", "$$this"] }
}
}
}
}
])
Sample Output
{
"_id" : 0,
"data" : [ 0, 4, 5, 6, 7 ]
}
just use $last
instead of $first
for s1
so the query becomes:
db.coll.aggregate(
{
$match : {
_id: { $in: [1, 2] }
}
},
{
$group: {
_id: 0,
s0: { $first: "$data"},
s1: { $last: "$data"}
}
},
{
$project: {
_id: 0,
ans: { $setUnion: [ "$s0","$s1"]}
}
}
).pretty()
output:
{ "ans" : [ 0, 4, 5, 6, 7 ] }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With