Reputation: 139
I have a set of documents of the form:
{
skill_id: 2,
skill_recs: [
{
_id: 4,
member_ids: [1, 4, 5]
}
]
},
{
skill_id: 5,
skill_recs: [
{
_id: 4,
member_ids: [1, 7, 9]
}
]
}
Now I want to aggregate a set of these documents such that skill_recs are combined by _id and the member_ids of all combined docs are merged into a single union of values...
{ _id: 4,
member_ids: [1, 4, 5, 7, 9]
}
I get most of the way with:
db.aggregate([
{
$unwind: '$skill_recs'
},
{
$group: {
_id: '$skill_recs._id',
all_member_ids: {$push: '$skill_recs.member_ids'}
}
},
{
$addFields: {
member_ids: {$setUnion: '$all_member_ids'}
}
}
])
but the $setUnion
doesn't do a union of the array of arrays that it is passed.
Instead it produces:
{ _id: 4,
member_ids: [[1, 4, 5], [1, 7, 9]]
}
Any way to produce the union of these arrays?
Upvotes: 2
Views: 633
Reputation: 22276
You're quite close, Here's a quick example of how to achieve this using $reduce
db.collection.aggregate([
{
$unwind: "$skill_recs"
},
{
$group: {
_id: "$skill_recs._id",
all_member_ids: {
$push: "$skill_recs.member_ids"
}
}
},
{
$addFields: {
member_ids: {
$reduce: {
input: "$all_member_ids",
initialValue: [],
in: {
$setUnion: [
"$$this",
"$$value"
]
}
}
}
}
}
])
Upvotes: 2