Reputation: 21865
Suppose we have the code :
EightWeekGamePlan.aggregate(
[
{ $sort: { Week: 1 } },
{
$group: {
_id: {
LeadId: "$LeadId",
BusinessName: "$BusinessName",
PhoneNumberMasque: "$PhoneNumberMasque",
City: "$City",
Rooms: "$Rooms"
// dateToString: { format: "%Y-%m-%d", date: "$InserDate" }
},
Weeks: {
$push: {
Week: "$Week",
Status: "$Status",
InsertDate: "$InsertDate",
TargetClient: "$TargetedToBeClaimedByClientType",
MaxClaims: "$TotalClaimsToBeClaimedByClientType",
CurrentClaims: "$TotalClaimsLeftToBeClaimedByClientType"
}
}
}
}
]
I'm grouping an then $pushing into an array , however another group is required before passing back the data to the client : how can we group the Weeks
array by Week
?
Please don't use another grouping of $Week
in the first $group
.
Example of the current answer (before the 2nd group), and I want to have it grouped again by the Week :
LeadId: "6823f5c6-244e-41aa-89eb-5d4d87fac068"
PhoneNumberMasque: "076-5465743856475"
BusinessName: "Something ... "
City: "Somewhere ..."
Rooms: 2
Weeks: Array(10): Array(10)
0: {Week: 1, Status: 1, InsertDate: "2019-12-27T08:44:26.000Z", TargetClient: 1, MaxClaims: 1, …}
1: {Week: 1, Status: 1, InsertDate: "2019-12-27T08:44:26.000Z", TargetClient: 2, MaxClaims: 2, …}
2: {Week: 1, Status: 1, InsertDate: "2019-12-27T08:44:26.000Z", TargetClient: 3, MaxClaims: 2, …}
3: {Week: 2, Status: 1, InsertDate: "2019-12-27T08:44:26.000Z", TargetClient: 2, MaxClaims: 5, …}
4: {Week: 3, Status: 1, InsertDate: "2019-12-27T08:44:26.000Z", TargetClient: 3, MaxClaims: 5, …}
5: {Week: 4, Status: 1, InsertDate: "2019-12-27T08:44:26.000Z", TargetClient: 4, MaxClaims: 5, …}
6: {Week: 5, Status: 1, InsertDate: "2019-12-27T08:44:26.000Z", TargetClient: 5, MaxClaims: 5, …}
7: {Week: 6, Status: 1, InsertDate: "2019-12-27T08:44:26.000Z", TargetClient: 6, MaxClaims: 5, …}
8: {Week: 7, Status: 1, InsertDate: "2019-12-27T08:44:26.000Z", TargetClient: 7, MaxClaims: 5, …}
9: {Week: 8, Status: 1, InsertDate: "2019-12-27T08:44:26.000Z", TargetClient: 8, MaxClaims: 5, …}
Upvotes: 1
Views: 64
Reputation: 4343
Although the added stage of @mickl seems to do the job, i would prefer to simply switch your $week field to from accumulator to your _id field of $group stage,
EightWeekGamePlan.aggregate(
[
{
$group: {
_id: {
LeadId: "$LeadId",
BusinessName: "$BusinessName",
PhoneNumberMasque: "$PhoneNumberMasque",
City: "$City",
Rooms: "$Rooms"
Weeks: "$Week",
},
Weeks: {
$push: {
Status: "$Status",
InsertDate: "$InsertDate",
TargetClient: "$TargetedToBeClaimedByClientType",
MaxClaims: "$TotalClaimsToBeClaimedByClientType",
CurrentClaims: "$TotalClaimsLeftToBeClaimedByClientType"
}
}
}
},
{ $sort: { "_id.Week": 1 } },
]
Note that here, your $sort stage as no real effect as first stage, but is more useful after grouping.
Upvotes: 1
Reputation: 49945
In case you don't want to use additional $group
stage you can take advantage of $reduce combined with $filter. $setUntion gives you an array of unique Week
numbers and then using $filter
you can bring matching documents from Weeks
array into your result set, combining subdocuments using $concatArrays:
db.collection.aggregate([
{
$project: {
Weeks: {
$reduce: {
input: { $setUnion: "$Weeks.Week" },
initialValue: [],
in: {
$concatArrays: [
"$$value",
[{
WeekNum: "$$this",
Docs: { $filter: { input: "$Weeks", as: "w", cond: { $eq: [ "$$w.Week", "$$this" ] } } }
}]
]
}
}
}
}
}
])
Upvotes: 1