I have a data model where each Product has many Variants and each Variant has many Modifications. In database it looks like this:
const mods = db.modifications.insertMany([
{
title: 'Modification #1',
image: 'img1.png',
},
{
title: 'Modification #2',
image: 'img2.png',
},
{
title: 'Modification #3',
image: 'img3.png',
},
])
db.products.insertOne({
slug: 'product1',
title: 'Product #1',
variants: [
{
size: 20,
price: 200,
modifications: [
{ id: mods.insertedIds[0], price: 10 },
{ id: mods.insertedIds[1], price: 15 },
],
},
{
size: 30,
price: 250,
modifications: [
{ id: mods.insertedIds[0], price: 15 },
{ id: mods.insertedIds[2], price: 20 },
],
},
],
})
What I want is to do
db.products.aggregate([
{ $match: { slug: 'product1' } },
// ?
])
to get the result that looks like this
const result = {
slug: 'product1',
title: 'Product #1',
variants: [
{
size: 20,
price: 200,
modifications: [
{ _id: '…', title: 'Modification #1', image: '…', price: 10 },
{ _id: '…', title: 'Modification #2', image: '…', price: 15 },
],
},
{
size: 30,
price: 250,
modifications: [
{ _id: '…', title: 'Modification #2', image: '…', price: 15 },
{ _id: '…', title: 'Modification #3', image: '…', price: 20 },
],
},
],
}
How to accomplish this?
I’ve tried to $unwind twice and then $lookup
db.products.aggregate([
{ $match: { slug: 'product1' } },
{ $unwind: '$variants' },
{ $unwind: '$variants.modifications' },
{
$lookup: {
from: 'modifications',
localField: 'variants.modifications.id',
foreignField: '_id',
let: { price: '$variants.modifications.price' },
pipeline: [{ $addFields: { price: '$$price' } }],
as: 'variants.modifications',
},
},
])
but then I don’t know how to $group (?) that data back.
Also, there’s a similar question with working solution. In my case though, the modifications array isn’t just array of ids, but has data within its elements (the price field) which I need to include in the result somehow.