I have a database in MongoDB like this
{"productId" : 1, "isVariant": 1, "variantId" : 1, "attributeSet" : [ { "name" : "Capacity", "value" : "500 GB", "id" : 3 }, { "name" : "Form Factor", "value" : "5 inch", "id" : 4 }, { "id" : 5, "name" : "Memory Components", "value" : "3D NAND" } ] }, {"productId" : 2, "isVariant": 1, "variantId" : 1, "attributeSet" : [ { "name" : "Capacity", "value" : "1 TB", "id" : 3 }, { "name" : "Form Factor", "value" : "5 inch", "id" : 4 }, { "id" : 5, "name" : "Memory Components", "value" : "3D NAND" } ] }, {"productId" : 3, "isVariant": 1, "variantId" : 1, "attributeSet" : [ { "name" : "Capacity", "value" : "500 GB", "id" : 3 }, { "name" : "Form Factor", "value" : "2.5 inch", "id" : 4 }, { "id" : 5, "name" : "Memory Components", "value" : "3D NAND" } ] }, {"productId" : 4, "isVariant": 1, "variantId" : 1, "attributeSet" : [ { "name" : "Capacity", "value" : "1 TB", "id" : 3 }, { "name" : "Form Factor", "value" : "2.5 inch", "id" : 4 }, { "id" : 5, "name" : "Memory Components", "value" : "3D NAND" } ] }
Now I want to return data where 500 GB has been in productId
1 and 3
The response should be like this:
variantValues : [{ attributeValue : "500 GB", data : [ {productId : 1}, {productId : 3} ]}, { attributeValue : "1 TB", data : [ {productId : 2}, {productId : 4} ]}, { attributeValue : "2.5 inch", data : [ {productId : 3}, {productId : 4} ]}, { attributeValue : "5 inch", data : [ {productId : 1}, {productId : 2} ]}]
I have the possible values that I store in another collection for variantPossible
values. The values that i am storing are like this:
"VariantValues" : { "3" : [ "500 GB", "1 TB" ], "4" : [ "2.5 inch", "5 inch" ] },
I want to return the variant values of each product if that product is a variant with the above format. can anyone help me with this.
Advertisement
Answer
You should be able to achieve this using $unwind
and $group
in your aggregation pipeline. This first flattens each attribute into a single document and on those you can group by the attribute value.
Finally, you can use $project
to get the desired name for attributeValue
:
db.collection.aggregate([ { $unwind: "$attributeSet" }, { $group: { _id: "$attributeSet.value", data: { "$addToSet": { productId: "$productId" } } } }, { "$project": { _id: 0, data: 1, attributeValue: "$_id" } } ])
See this simplifed example on mongoplayground: https://mongoplayground.net/p/VASadZnDedc