This is how the Order model is structured
new Schema(
{
...
products: [
{
_id: String,
title: String,
image: [String],
category: String,
purity: String,
metal: String,
weight: String,
gemstone: {
weight: Number,
category: String,
purity: String,
shape: String,
color: String,
clarity: String,
},
qty: Number,
price: Number,
},
],
user: {type: String},
shop: { type: String, required: true },
type: { type: String, required: true, enum: ["product", "scheme"] },
}
Now I need to query data based on a shopId
and type: "product"
. But I want the operation to return data in the following format
[
{
category: "ring",
products: [{...productObject, users: [userIds]}],
}
]
Rest of the fields are not needed. So basically I want to group users for each product and then group products according to category that each product has.
I know I can just query the data directly and then perform a bunch of array operations to somehow get data like this. I was just wondering if we could use aggregate to do all this in a single opearation and make it more performant.
I should let you know that this is in a separate microservice using a different database so I can't directly just link Ids. All data is supposed to taken from this model with no external joins.
I have tried this aggregate query
orders = await Order.aggregate([
{
$match: {
shop: shopId,
type: "product",
},
},
{
$unwind: "$products",
},
{
$group: {
_id: "$products.category",
products: {
$push: {
users: "$user",
product: "$products",
},
},
},
},
{
$project: {
_id: false,
category: "$_id",
products: 1,
},
},
]);
This returns data like this
[
{
category: "ring",
products: [
{
users: "63761866b2e154f25fcebd95",
product: {
...,
_id: "6375ff628fbcdb23c333ee48"
}
},
{
users: "637605b0b2e154f25fceb520",
product: {
...,
_id: "6375ff628fbcdb23c333ee48",
}
},
{
users: "637605b0b2e154f25fceb520",
product: {
...,
_id: "6375ff5d8fbcdb23c333ee44",
}
},
{
users: "63761866b2e154f25fcebd95",
product: {
...,
_id: "6375ff5d8fbcdb23c333ee44",
}
},
{
users: "63761866b2e154f25fcebd95",
product: {
...,
_id: "6375ff628fbcdb23c333ee48",
}
}
]
}
]
As you can see I am able to group by category but I still want to merge products with same _id
and make the users
as an array for the different ids. Also it would be great if I could avoid the extra product
field in products
array and just combine users with products
elements.
Basically, the above should look like this
[
{
category: "ring",
products: [
{
...productDetails,
_id: "6375ff628fbcdb23c333ee48",
users: ["63761866b2e154f25fcebd95", "637605b0b2e154f25fceb520"]
},
{
...productDetails,
_id: "6375ff5d8fbcdb23c333ee44",
users: ["63761866b2e154f25fcebd95", "637605b0b2e154f25fceb520"]
}
]
}
]
Any help is appreciated! If possible please do explain your operation!