I have a collection that looks something like:
[
{
"_id": "5f0307520ac9361c0d7088e2",
"productId": 1,
"stock": 10,
"unit": "item",
"price": 20,
"images": [
"http://productimages.com/1/001.jpg",
"http://productimages.com/1/002.jpg"
]
},
{
"_id": "5f0307520ac9361c0d7088e3",
"productId": 1,
"stock": 20,
"unit": "item",
"price": 30,
"images": [
"http://productimages.com/1/003.jpg",
"http://productimages.com/1/004.jpg"
]
},
{
"_id": "5f0307520ac9361c0d7088e4",
"productId": 2,
"stock": 5,
"unit": "item",
"price": 15,
"images": [
"http://productimages.com/2/001.jpg",
"http://productimages.com/2/002.jpg"
]
},
{
"_id": "5f0307520ac9361c0d7088e5",
"productId": 2,
"stock": 5,
"unit": "item",
"price": 12,
"images": [
"http://productimages.com/2/003.jpg",
"http://productimages.com/2/004.jpg"
]
}
]
And I aggregate it as follows:
db.variants.aggregate([
{
"$group": {
"_id": "$productId",
"price": { "$min": "$price" },
"stock": { "$sum": "$stock" },
"unit": { "$first": "$unit" },
"images": { "$push": "$images" },
"variants": { "$push": "$$ROOT" }
}
}
]).pretty()
which produces the following output:
[
{
"_id": 2,
"price": 12,
"stock": 10,
"unit": "item",
"images": [
[
"http://productimages.com/2/001.jpg",
"http://productimages.com/2/002.jpg"
],
[
"http://productimages.com/2/003.jpg",
"http://productimages.com/2/004.jpg"
]
],
"variants": [
{
"_id": "5f0307520ac9361c0d7088e4",
"productId": 2,
"stock": 5,
"unit": "item",
"price": 15,
"images": [
"http://productimages.com/2/001.jpg",
"http://productimages.com/2/002.jpg"
]
},
{
"_id": "5f0307520ac9361c0d7088e5",
"productId": 2,
"stock": 5,
"unit": "item",
"price": 12,
"images": [
"http://productimages.com/2/003.jpg",
"http://productimages.com/2/004.jpg"
]
}
]
},
{
"_id": 1,
"price": 20,
"stock": 30,
"unit": "item",
"images": [
[
"http://productimages.com/1/001.jpg",
"http://productimages.com/1/002.jpg"
],
[
"http://productimages.com/1/003.jpg",
"http://productimages.com/1/004.jpg"
]
],
"variants": [
{
"_id": "5f0307520ac9361c0d7088e2",
"productId": 1,
"stock": 10,
"unit": "item",
"price": 20,
"images": [
"http://productimages.com/1/001.jpg",
"http://productimages.com/1/002.jpg"
]
},
{
"_id": "5f0307520ac9361c0d7088e3",
"productId": 1,
"stock": 20,
"unit": "item",
"price": 30,
"images": [
"http://productimages.com/1/003.jpg",
"http://productimages.com/1/004.jpg"
]
}
]
}
]
however I would like to get
[
{
"_id": 2,
"price": 12,
"stock": 10,
"unit": "item",
"images": [
"http://productimages.com/2/001.jpg",
"http://productimages.com/2/002.jpg",
"http://productimages.com/2/003.jpg",
"http://productimages.com/2/004.jpg"
],
"variants": [
{
"_id": "5f0307520ac9361c0d7088e4",
"productId": 2,
"stock": 5,
"unit": "item",
"price": 15,
"images": [
"http://productimages.com/2/001.jpg",
"http://productimages.com/2/002.jpg"
]
},
{
"_id": "5f0307520ac9361c0d7088e5",
"productId": 2,
"stock": 5,
"unit": "item",
"price": 12,
"images": [
"http://productimages.com/2/003.jpg",
"http://productimages.com/2/004.jpg"
]
}
]
},
{
"_id": 1,
"price": 20,
"stock": 30,
"unit": "item",
"images": [
"http://productimages.com/1/001.jpg",
"http://productimages.com/1/002.jpg",
"http://productimages.com/1/003.jpg",
"http://productimages.com/1/004.jpg"
],
"variants": [
{
"_id": "5f0307520ac9361c0d7088e2",
"productId": 1,
"stock": 10,
"unit": "item",
"price": 20,
"images": [
"http://productimages.com/1/001.jpg",
"http://productimages.com/1/002.jpg"
]
},
{
"_id": "5f0307520ac9361c0d7088e3",
"productId": 1,
"stock": 20,
"unit": "item",
"price": 30,
"images": [
"http://productimages.com/1/003.jpg",
"http://productimages.com/1/004.jpg"
]
}
]
}
]
instead. I have tried replacing the images expression with images.* but this produced an empty set.
I have also tried adding a $reduce projection to the pipeline as shown at combine array fields into a single array field mongo:
db.variants.aggregate([
{
"$group": {
"_id": "$productId",
"price": { "$min": "$price" },
"stock": { "$sum": "$stock" },
"unit": { "$first": "$unit" },
"images": { "$push": "$images" },
"variants": { "$push": "$$ROOT" }
}
},
{
"$project": {
"images": {
"$reduce": {
"input": { "$concatArrays": ["images.*"] },
"initialValue": [],
"in": { "$setUnion": ["$$this", "$$value"] }
}
}
}
}
]).pretty()
which fails with:
{
"ok" : 0,
"errmsg" : "Failed to optimize pipeline :: caused by :: $concatArrays only supports arrays, not string",
"code" : 28664,
"codeName" : "Location28664"
}
$groupto flatten your array of arrays, just like in that exampleinput: "$images", there's no syntax with asterisk