Reputation: 567
I have the following schema in my collection:
{
_id: ObjectId,
foo: [
{
bar_id: ObjectId,
bar_list: [
{...},
{...},
]
},
{
bar_id: ObjectId,
bar_list: [
{...},
{...},
]
}
...
]
],
relations: {
relation_type: [
{
relation_id: ObjectId,
...
}
]
...
}
}
I wish to create a new document that has a similar structure (relations
is not needed in the new document) as the input documents but that is an aggregation on relation_id
and where the bar_list
arrays of each input document has been concatenated (including duplicates).
To illustrate:
Document 1
{
_id: 1,
foo: [
{
bar_id: 77,
bar_list: [
{a, b},
{c, d},
]
},
{
bar_id: 88,
bar_list: [
{u, v},
{w, x},
{y, z},
]
}
]
],
relations: {
relation_type: [
{
relation_id: 666,
...
}
]
...
}
}
Document 2
{
_id: 2,
foo: [
{
bar_id: 77,
bar_list: [
{a, b},
{e, f},
{g, h},
]
},
{
bar_id: 88,
bar_list: [
{u, v},
]
}
]
],
relations: {
relation_type: [
{
relation_id: 666,
...
}
]
...
}
}
Output Document
{
foo: [
{
bar_id: 77,
bar_list: [
{a, b},
{c, d},
{a, b},
{e, f},
{g, h},
]
},
{
bar_id: 88,
bar_list: [
{u, v},
{w, x},
{y, z},
{u, v},
]
}
]
],
}
The first part of filtering for a match against the relations.relation_type.relation_id
is easy. But how to I concatenate the array based on bar_id
and format the result as required? Here is what I have so far:
db.getCollection('example').aggregate([
{'$match': {'relations.relation_type.relation_id': 666}},
// Some sore of $group, $mergeObjects or $concatArrays next?
])
Any help appreciated.
Upvotes: 2
Views: 2060
Reputation: 13103
foo
.bar_id
and accumulate bar_list
array with key:pair
values.bar_list
arrays_id
fielddb.collection.aggregate([
{
"$match": {
"relations.relation_type.relation_id": 666
}
},
{
$unwind: "$foo"
},
{
$group: {
_id: "$foo.bar_id",
bar_list: {
$push: "$foo.bar_list"
}
}
},
{
$project: {
_id: 0,
bar_id: "$_id",
bar_list: {
$reduce: {
input: "$bar_list",
initialValue: [],
in: {
$concatArrays: [
"$$value",
"$$this"
]
}
}
}
}
},
{
$group: {
_id: null,
foo: {
$push: "$$ROOT"
}
}
},
{
$project: {
_id: 0
}
}
])
Upvotes: 2