I have an aggregation use case where I have a large JSON containing product orders data that I need to aggregate.
Below is a small subset of the data which I am planning to aggregate and seek your assistance.
[
{
"orderid": "1111",
"order_type": "individual",
"users": [
{
"name": "user1",
"phone": 982928,
"items": [
{
"name": "AAA",
"qty": 20,
"price": 10
},
{
"name": "BBB",
"qty": 30,
"price": 15
}
]
},
{
"name": "user2",
"phone": 948783,
"items": [
{
"name": "AAA",
"qty": 10,
"price": 10
},
{
"name": "CCC",
"qty": 5,
"price": 20
}
]
},
{
"name": "user3",
"phone": 787868,
"items": [
{
"name": "BBB",
"qty": 40,
"price": 10
},
{
"name": "CCC",
"qty": 15,
"price": 20
}
]
}
]
},
{
"orderid": "2222",
"order_type": "bulk",
"users": [
{
"name": "user1",
"phone": 982928
},
{
"name": "user3",
"phone": 787868
}
],
"items": [
{
"name": "AAA",
"qty": 3,
"price": 10
},
{
"name": "BBB",
"qty": 15,
"price": 10
}
]
}
]
A bit of explanation about the structure of the JSON structure.
The JSON array contains a mix of JSON objects with a differentiator being order_type field as a deciding factor of how the orders are structured.
The output I am looking to achieve would look something like:
[
{
"user":"user1",
"orders":[1111,2222],
"unique_items":2
},
{
"user":"user2",
"orders":[1111],
"unique_items":2
},
{
"user":"user3",
"orders":[1111,2222],
"unique_items":3
}
]
A logical view(from my viewpoint) of how the data is to be aggregated in a pipeline, the aggregation should begin by selecting all distinct users appearing in all the array elements and proceed with combining orderid(s) that contains orders where each user is present and then proceed with calculating number of unique product/item name(s) appearing in each of the order for that user. This way the algorithm should proceed with and output the resultant JSON structure above.
I am relatively new at aggregation, any help in this regard would be highly appreciated.
users
array.users
into documents with $unwind
Could be this one:
db.collection.aggregate([
{
$set: {
items: "$$REMOVE",
users: {
$map: {
input: "$users",
in: { $mergeObjects: [ "$$this", { items: "$items" } ] }
}
}
}
},
{ $unwind: "$users" },
{
$group: {
_id: "$users.name",
orders: { $addToSet: "$orderid" },
unique_items: { $addToSet: "$users.items.name" }
}
},
{
$set: {
items: {
$reduce: {
input: "$unique_items",
initialValue: [],
in: { $concatArrays: [ "$$value", "$$this" ] }
}
}
}
},
{
$set: {
items: "$$REMOVE",
unique_items: { $size: { $setUnion: "$items" } }
}
}
])