I am using Mongo aggregate framework, suppose if i am having collection structure like this
[ { _id: 123, name: "john", age: 30, fruit: "apple", }, { _id: 345, name: "moore", age: 45, fruit: "mango", }, { _id: 545, name: "carl", age: 30, fruit: "grape", }, { _id: 96, name: "shelby", age: 25, fruit: "apple", }, { _id: 86, name: "loris", age: 48, fruit: "mango", }, { _id: 76, name: "carl", age: 55, fruit: "grape" } ]
I want to query and create a pipeline such that it return the count of particular fruit which lie under the duration which $bucket boudaries have created: for example result should look like this...
[ { "_id": Specific_Boudary, "userCount": Number_Of_Users_Lie, "fruitsLie": [ {fruit_names_of_user_in_this_boundaries: fruit_counts}, ] }, { "_id": 0, "userCount": 3, "fruitsLie": [ {apple: 2}, {grape: 1} ] }, { "_id": 40, "userCount": 2, "fruitsLie": [ {mango: 2} ] }, { "_id": "more than 50", "userCount": 1, "fruitsLie": [ {grape: 1} ] } ]
so under age 30 we have 3 users, in which 2 eats apple and 1 eats grape so fruitsLie
field is responsible for this calculation.
how many approaches we can have to achieve the solution for this problem with specific $bucket boudaries and please explain thoroughly each stage, I am new to aggregate and currently learning...
This is one way of doing this:
db.collection.aggregate([
{
"$bucket": {
"groupBy": "$age",
"boundaries": [
0,
31,
41,
51,
],
"default": "More than 50",
"output": {
"users": {
$push: "$$ROOT"
}
}
}
},
{
"$unwind": "$users"
},
{
"$group": {
"_id": {
_id: "$_id",
fruit: "$users.fruit"
},
"count": {
"$sum": 1
},
}
},
{
"$group": {
"_id": "$_id._id",
"fruitsLie": {
"$push": {
"$concatArrays": [
[],
[
[
"$$ROOT._id.fruit",
"$$ROOT.count"
]
]
]
}
},
usersCount: {
$sum: "$$ROOT.count"
}
}
},
{
"$addFields": {
"fruitsLie": {
"$map": {
"input": "$fruitsLie",
"as": "item",
"in": {
"$arrayToObject": "$$item"
}
}
}
}
}
])
In this query, we do the following:
Using $bucket, we group the documents by age into 4 buckets, (0-30), (31-40), (41-50), and (>50). We collect all the users within a bucket into an array.
Now, we unwind the users array, using $unwind.
Now, using $group, we calculate, the counts for each fruit within each bucket.
Again using $group, now we accumulate counts for each bucket, into fruitsLie
array.
Finally, using $arrayToObject
, we convert elements of fruitLie
array to a object.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.