I am new to Mongo DB query. Here I have a collection of documents in the below structure. As a top level, need to group based on label and below that based on role and their corresponding status grouping. Since it is nested I have tried with $objectToArray
[
{
"_id": "637f58f205b3fcaa10767ab6",
"status": {
"MAN": "inprogress",
"DEV": "new",
"TEST": "new"
},
"label": "ABC1"
},
{
"_id": "637f58f205b3fcaa10767ab7",
"status": {
"MAN": "inprogress",
"DEV": "completed",
"TEST": "inprogress"
},
"label": "ABC2"
},
{
"_id": "637f58f205b3fcaa10767ab8",
"status": {
"MAN": "completed",
"DEV": "new",
"TEST": "completed"
},
"label": "ABC3"
},
{
"_id": "637f58f205b3fcaa10767ab9",
"status": {
"MAN": "new",
"DEV": "completed",
"TEST": "inprogress"
},
"label": "ABC1"
},
{
"_id": "637f58f205b3fcaa10767ac1",
"status": {
"MAN": "new",
"DEV": "completed",
"TEST": "inprogress"
},
"label": "ABC2"
}
]
I am using the following aggregate:
db.getCollection("requirements").aggregate([
{ "$addFields": {
"status": {
"$map": {
"input": { "$objectToArray": "$status" },
"as": "el",
"in": {
"$concat": ["$$el.k", "_", "$$el.v"]
}
}
}
} },
{ "$unwind": "$status" },
{
$group: {
_id: {label: "$label",roleGroup: "$status"},
totalCount: { $sum: 1}
}
},
{
$group:{
_id:"$_id.label",
roleGroups:{$push:{roleGroup:"$_id.roleGroup", totalCount:"$totalCount"}}
}
}
])
And am able to get the following output:
{
"_id" : null,
"counts" : [
{
"k" : "ABC3",
"v" : [
{
"roleGroup" : "DEV_completed",
"totalCount" : 1.0
},
{
"roleGroup" : "MAN_inprogress",
"totalCount" : 1.0
},
{
"roleGroup" : "MAN_completed",
"totalCount" : 1.0
},
{
"roleGroup" : "MAN_new",
"totalCount" : 1.0
},
{
"roleGroup" : "DEV_inprogress",
"totalCount" : 1.0
},
{
"roleGroup" : "DEV_new",
"totalCount" : 1.0
},
{
"roleGroup" : "TEST_new",
"totalCount" : 2.0
},
{
"roleGroup" : "TEST_inprogress",
"totalCount" : 1.0
}
]
},
{
"k" : "ABC2",
"v" : [
{
"roleGroup" : "DEV_inprogress",
"totalCount" : 1.0
},
{
"roleGroup" : "MAN_completed",
"totalCount" : 1.0
},
{
"roleGroup" : "MAN_new",
"totalCount" : 1.0
},
{
"roleGroup" : "TEST_new",
"totalCount" : 2.0
},
{
"roleGroup" : "DEV_new",
"totalCount" : 1.0
}
]
},
{
"k" : "ABC4",
"v" : [
{
"roleGroup" : "TEST_new",
"totalCount" : 1.0
},
{
"roleGroup" : "DEV_new",
"totalCount" : 1.0
},
{
"roleGroup" : "MAN_new",
"totalCount" : 1.0
}
]
},
{
"k" : "ABC1",
"v" : [
{
"roleGroup" : "TEST_new",
"totalCount" : 3.0
},
{
"roleGroup" : "MAN_new",
"totalCount" : 3.0
},
{
"roleGroup" : "DEV_new",
"totalCount" : 3.0
}
]
}
]
}
But I want the output like below:
[
{
"_id": "ABC1",
"MAN": {
"new": 1,
"inprogress": 2,
"completed": 1
},
"DEV": {
"new": 1,
"inprogress": 2,
"completed": 1
},
"TEST": {
"new": 1,
"inprogress": 2,
"completed": 1
},
"totalCount": 4
},
{
"_id": "ABC2",
"MAN": {
"new": 1,
"inprogress": 2,
"completed": 1
},
"DEV": {
"new": 1,
"inprogress": 2,
"completed": 1
},
"TEST": {
"new": 1,
"inprogress": 2,
"completed": 1
},
"totalCount": 4
}
]
I really need some of your inputs to get this format. Thanks in advance
Related
I have documents like these :
Merchant:
{
"_id" : ObjectId("628728cf9f5c99d8dedbe759"),
"name" : "agriTales",
"information" : "Farmers social",
"categories" : [
ObjectId("6287220c52497922d6f4a121")
],
"website" : "www.agritales.com",
"active" : true
}
LuckyDraw:
{
"_id" : ObjectId("62873487e0e5eedc24748a55"),
"business" : ObjectId("628728cf9f5c99d8dedbe759"),
"title" : "May Lucky draw 2022",
"date_start" : ISODate("2022-04-26T00:00:00Z"),
"max_participants" : 5,
"active" : true,
"date_of_draw" : ISODate("2022-07-30T00:00:00Z"),
"prizes_winners" : [
{
"prize_name" : "1st Prize",
"coupon_voucher" : ObjectId("62872f809f5c99d8dedbe764")
},
{
"prize_name" : "2nd Prize",
"coupon_voucher" : ObjectId("62872f8d9f5c99d8dedbe765")
}
],
"result_declared" : true
}
CouponVoucher:
{
"_id" : ObjectId("62872f809f5c99d8dedbe764"),
"business" : ObjectId("628728cf9f5c99d8dedbe759"),
"type" : "voucher",
"title" : "8farmers Coupons 2001",
"minimum_order_value" : 0,
"voucher_face_value" : 2001,
"active" : true,
"status" : "NEW",
"date_expiry" : ISODate("2022-12-31T00:00:00Z"),
}
{
"_id" : ObjectId("62872f8d9f5c99d8dedbe765")
"type" : "voucher",
"title" : "8farmers Coupons 1501",
"minimum_order_value" : 0,
"voucher_face_value" : 1501,
"active" : true,
"status" : "NEW",
"date_expiry" : ISODate("2022-12-31T00:00:00Z")
}
class LuckyDraws(Document):
business = ReferenceField(Merchants, required=True)
branches = ListField(ReferenceField(MerchantBranches))
title = StringField(required=True)
date_start = DateTimeField(required=True) # the date when luck draw will be available to participate
max_participants = IntField() # max number of participants
active = BooleanField(default=True)
date_of_draw = DateTimeField(required=True) # the date when luck draw will be declared
filter_conditions = EmbeddedDocumentField(LuckyDrawFilterConditions)
participants = ListField(ReferenceField(Users), required=False)
prizes_winners = ListField(EmbeddedDocumentField(LuckyDrawPrizesWinners), required=True)
class LuckyDrawPrizesWinners(EmbeddedDocument):
prize_name = StringField(required=True)
coupon_voucher = ReferenceField(CouponVoucher, required=True)
winner = ReferenceField(Users, blank=True, null=True, default=None)
class CouponVoucher(Document):
business = ReferenceField(Merchants, required=True)
title = StringField(required=True, unique=True)
discount_type = StringField(required=False) # amount / percentage
coupon_discount = DecimalField(required=False)
max_count = IntField(required=False)
minimum_order_value = DecimalField(required=False)
I am looking for a result where I get details of the lucky draw and its corresponding prizes and couponvoucher details
used below pipeline
LuckyDraws.objects.aggregate([{
'$lookup':
{
"from": "merchants",
"localField": "business",
"foreignField": "_id",
"as": "business",
"pipeline": [
{"$project": {"name": 1, "information": 1, "categories": 1}}
]
}
},
{"$project":
{
"business": 1, "title": 1, "date_start": 1, "active": 1, "date_of_draw": 1,
"prizes_winners.prize_name": 1, "prizes_winners.coupon_voucher": 1,
"result_declared": 1, "vouchers": 1
}
},
{
'$lookup':
{
"from": "coupon_voucher",
"localField": "prizes_winners.coupon_voucher",
"foreignField": "_id",
"pipeline": [
{"$project": {"title": 1, "minimum_order_value": 1, "voucher_face_value": 1,
"active": 1, "date_expiry": 1}}
],
"as": "prizes_winners"
}
},
{
"$sort": {
"date_of_draw": -1
}
}
]
and getting below results but its missing prize_name under prizes_winners, please let me know what I am missing and how t oadd prize_name under prizes_winners.
the result i am getting :
[
{
"_id": {
"$oid": "62873487e0e5eedc24748a55"
},
"business": [
{
"_id": {
"$oid": "628728cf9f5c99d8dedbe759"
},
"name": "agriTales",
"information": "Farmers social",
"categories": [
{
"$oid": "6287220c52497922d6f4a121"
}
]
}
],
"title": "May Lucky draw 2022",
"date_start": {
"$date": "2022-04-26T00:00:00Z"
},
"active": true,
"date_of_draw": {
"$date": "2022-07-30T00:00:00Z"
},
"prizes_winners": [
{
"_id": {
"$oid": "62872f809f5c99d8dedbe764"
},
"title": "8farmers Coupons 2001",
"minimum_order_value": 0.0,
"voucher_face_value": 2001.0,
"active": true,
"date_expiry": {
"$date": "2022-12-31T00:00:00Z"
}
},
{
"_id": {
"$oid": "62872f8d9f5c99d8dedbe765"
},
"title": "8farmers Coupons 1501",
"minimum_order_value": 0.0,
"voucher_face_value": 1501.0,
"active": true,
"date_expiry": {
"$date": "2022-12-31T00:00:00Z"
}
}
],
"result_declared": true
}
]
I want the result should be :
[
{
"_id": {
"$oid": "62873487e0e5eedc24748a55"
},
"business": [
{
"_id": {
"$oid": "628728cf9f5c99d8dedbe759"
},
"name": "agriTales",
"information": "Farmers social",
"categories": [
{
"$oid": "6287220c52497922d6f4a121"
}
]
}
],
"title": "May Lucky draw 2022",
"date_start": {
"$date": "2022-04-26T00:00:00Z"
},
"active": true,
"date_of_draw": {
"$date": "2022-07-30T00:00:00Z"
},
"prizes_winners": [
{
**"prize_name":"1st prize",**
"_id": {
"$oid": "62872f809f5c99d8dedbe764"
},
"title": "8farmers Coupons 2001",
"minimum_order_value": 0.0,
"voucher_face_value": 2001.0,
"active": true,
"date_expiry": {
"$date": "2022-12-31T00:00:00Z"
}
},
{
**"prize_name":"2nd prize",**
"_id": {
"$oid": "62872f8d9f5c99d8dedbe765"
},
"title": "8farmers Coupons 1501",
"minimum_order_value": 0.0,
"voucher_face_value": 1501.0,
"active": true,
"date_expiry": {
"$date": "2022-12-31T00:00:00Z"
}
}
],
"result_declared": true
}
]
There are lots of ways, and possibly more efficient ways, to do this. Here's one way.
db.LuckyDraw.aggregate([
{
"$lookup": {
"from": "Merchant",
"localField": "business",
"foreignField": "_id",
"pipeline": [ { "$unset": [ "active", "website" ] } ],
"as": "business"
}
},
{
"$lookup": {
"from": "CouponVoucher",
"localField": "prizes_winners.coupon_voucher",
"foreignField": "_id",
"let": { "prizes_winners": "$prizes_winners" },
"pipeline": [
{
"$set": {
"prize_name": {
"$reduce": {
"input": "$$prizes_winners",
"initialValue": "",
"in": {
"$cond": [
{ "$eq": [ "$$this.coupon_voucher", "$_id" ] },
"$$this.prize_name",
"$$value"
]
}
}
}
}
}
],
"as": "prizes_winners"
}
}
])
Try it on mongoplayground.net.
Following is my query does exactly match with my document but still not getting output.Don't know why. Following is the document as well.
db.getCollection("analytics").find(
{
"$and" : [
{
"archive" : false
},
{
"platform" : "WEB"
},
{
"vendorId" : "3c7adbfe-14d7-4b26-9134-7e05d56573cc"
},
{
"createdAt" : {
"$gte" : 1578268800000.0
}
},
{
"createdAt" : {
"$lte" : 1580860800000.0
}
},
{
"$and" : [
{
"data.mobile" : "123"
},
{
"page" : "Loan Application"
},
{
"event" : "click"
}
]
},
{
"$and" : [
{
"data.aadharNumber" : "123"
},
{
"page" : "Personal Information"
},
{
"event" : "click"
}
]
},
{
"$and" : [
{
"data.totalExp" : "5"
},
{
"page" : "Professional Information"
},
{
"event" : "click"
}
]
}
]
}
);
Documents :
[
{
"page": "Loan Application",
"event": "click",
"loggedIn": true,
"vendorId": "3c7adbfe-14d7-4b26-9134-7e05d56573cc",
"data": {
"first": "Praveen",
"mobile": "1234"
},
"platform": "WEB"
},
{
"page": "Personal Information",
"event": "click",
"loggedIn": true,
"vendorId": "3c7adbfe-14d7-4b26-9134-7e05d56573cc",
"data": {
"panNumber": "123",
"aadharNumber": "123"
},
"platform": "WEB"
},
{
"page": "Professional Information",
"event": "click",
"loggedIn": true,
"vendorId": "3c7adbfe-14d7-4b26-9134-7e05d56573cc",
"data": {
"totalExp": "5"
},
"platform": "WEB"
}
]
There are a lot of issues going on with your query, you can try below query to return all documents :
db.getCollection("analytics").find({
$expr: {
$and: [
{
$eq: [
"$platform",
"WEB"
]
},
{
$eq: [
"$vendorId",
"3c7adbfe-14d7-4b26-9134-7e05d56573cc"
]
},
{
$or: [
{
"$and": [
{
"data": {
"mobile": "123"
}
},
{
"page": "Loan Application"
},
{
"event": "click"
}
]
},
{
"$and": [
{
"data": {
"aadharNumber": "123"
}
},
{
"page": "Personal Information"
},
{
"event": "click"
}
]
},
{
"$and": [
{
"data": {
"totalExp": "5"
}
},
{
"page": "Professional Information"
},
{
"event": "click"
}
]
}
]
}
]
}
})
Test : MongoDB-Playground
I have the following result. Below it would be possible to make a map joining the array each with its objectid.
{
"_id": ObjectId("597233b50e717e0585dbd94a"),
"createdAt": ISODate("2017-07-21T17:02:45.119+0000"),
"name": "cardoso",
"gender": "female",
"profile": [{
"profession": "master",
"_id": ObjectId("597233b50e717e0585dbd94b"),
"departament": ObjectId("597233b50e717e0585dbd94e")
},
{
"_id": ObjectId("59766719003e7d552fe40e8c"),
"profession": "master",
"departament": ObjectId("59766719003e7d552fe40e8b")
},
{
"_id": ObjectId("5976b8f99d8a4326c6bf1ae5"),
"profession": "master",
"departament": ObjectId("5974d8fe398e5b2fd433410f")
}
],
"Institution": {
"_id": ObjectId("597233b50e717e0585dbd94c"),
"cnpj": 64837134000144.0,
"deletedAt": false,
"departament": [{
"title": "cardoso",
"category": "Sub-17",
"_id": ObjectId("597233b50e717e0585dbd94e")
},
{
"sport": "Tênis",
"title": "novo",
"category": "Sub-12",
"_id": ObjectId("59766719003e7d552fe40e8b")
},
{
"_id": ObjectId("5974d8fe398e5b2fd433410f"),
"category": "Intercâmbio",
"title": "testeJJJ",
"sport": "natação"
}
]
}
}
I need to do the following result. I did not want to have to manipulate the result in the node.
{
"sport": "Tênis",
"profession": "master",
"title": "novo",
"category": "Sub-12",
"_id": ObjectId("59766719003e7d552fe40e8b")
}
I already tended to do something but the query ends up getting very big
The basic premise here is to "lookup" the content in the other array whilst processing via $map.
This is either done via $indexOfArray with MongoDB 3.4:
db.collection.aggregate([
{ "$addFields": {
"Institution": {
"departament": {
"$map": {
"input": "$Institution.departament",
"as": "d",
"in": {
"sport": "$$d.title",
"profession": {
"$arrayElemAt": [
"$profile.profession",
{ "$indexOfArray": [ "$profile.departament", "$$d._id" ] }
]
},
"title": "$$d.title",
"category": "$$d.category"
}
}
}
}
}}
])
In that first index we look for the "index position" from the "profile" array that matches the current value of _id on the specified field. Then extract the data at that index via $arrayElemAt.
Or using $filter and the $arrayElemAt "the other way around" with MongoDB 3.2:
db.collection.aggregate([
{ "$addFields": {
"Institution": {
"departament": {
"$map": {
"input": "$Institution.departament",
"as": "d",
"in": {
"sport": "$$d.title",
"profession": {
"$arrayElemAt": [
{ "$map": {
"input": {
"$filter": {
"input": "$profile",
"as": "p",
"cond": { "$eq": [ "$$p.departament", "$$d._id" ] }
}
},
"as": "p",
"in": "$$p.profession"
}},
0
]
},
"title": "$$d.title",
"category": "$$d.category"
}
}
}
}
}}
])
In which case the $filter reduces the array content in "profile" down to only matching elements, which should be just one. This is then extracted at the 0 index by $arrayElemAt.
Same result in either case:
{
"_id" : ObjectId("597233b50e717e0585dbd94a"),
"createdAt" : ISODate("2017-07-21T17:02:45.119Z"),
"name" : "cardoso",
"gender" : "female",
"profile" : [
{
"profession" : "master",
"_id" : ObjectId("597233b50e717e0585dbd94b"),
"departament" : ObjectId("597233b50e717e0585dbd94e")
},
{
"_id" : ObjectId("59766719003e7d552fe40e8c"),
"profession" : "master",
"departament" : ObjectId("59766719003e7d552fe40e8b")
},
{
"_id" : ObjectId("5976b8f99d8a4326c6bf1ae5"),
"profession" : "master",
"departament" : ObjectId("5974d8fe398e5b2fd433410f")
}
],
"Institution" : {
"_id" : ObjectId("597233b50e717e0585dbd94c"),
"cnpj" : 64837134000144.0,
"deletedAt" : false,
"departament" : [
{
"sport" : "cardoso",
"profession" : "master",
"title" : "cardoso",
"category" : "Sub-17"
},
{
"sport" : "novo",
"profession" : "master",
"title" : "novo",
"category" : "Sub-12"
},
{
"sport" : "testeJJJ",
"profession" : "master",
"title" : "testeJJJ",
"category" : "Intercâmbio"
}
]
}
}
I have following Mongodb document. Would like to fetch document where participant = 'xxx' and (message.touserid = 'xxx' or message.fromuserid = 'xxx').
I am using following query but it is returning all messages instead of just one. Could you please let me know how to achieve this result?
{ "$and" : [ { "participants" : { "$regex" : "56d314a8e4b04d7f98cfd0c6"} , "$or" : [ { "messages.touserId" : "56d314a8e4b04d7f98cfd0c6"} , { "messages.formuserId" : "56d314a8e4b04d7f98cfd0c6"}]}]} fields: { "_id" : "0" , "product" : "0" , "participants" : "0" , "messages" : "0"}
{
"_id": {
"$oid": "574eb878027520c2158268d6"
},
"_class": "com.idearealty.product.shopchat.persistence.model.Discussion",
"participants": "56d314a8e4b04d7f98cfd0c6,56d5d48ee4b0cc330f512a47,56d9d599e4b0cc330f512aaa,57130299e4b08c554c1092c7,56841002eceefce22f455c7f",
"messages": [
{
"_id": {
"$oid": "574eb874027520c2158268d2"
},
"formuserId": "56841002eceefce22f455c7f",
"fromuser": "9674642375",
"touserId": "56d314a8e4b04d7f98cfd0c6",
"touser": "debopam_r",
"message": "Creating Discussion",
"isMute": false,
"index": 1,
"createDate": {
"$date": "2016-06-01T10:27:00.500Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:00.501Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
},
{
"_id": {
"$oid": "574eb875027520c2158268d3"
},
"formuserId": "56841002eceefce22f455c7f",
"fromuser": "9674642375",
"touserId": "56d5d48ee4b0cc330f512a47",
"touser": "Raushan",
"message": "Creating Discussion",
"isMute": false,
"index": 2,
"createDate": {
"$date": "2016-06-01T10:27:01.295Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:01.295Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
},
{
"_id": {
"$oid": "574eb875027520c2158268d4"
},
"formuserId": "56841002eceefce22f455c7f",
"fromuser": "9674642375",
"touserId": "56d9d599e4b0cc330f512aaa",
"touser": "anirbanshop1",
"message": "Creating Discussion",
"isMute": false,
"index": 3,
"createDate": {
"$date": "2016-06-01T10:27:01.962Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:01.962Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
},
{
"_id": {
"$oid": "574eb876027520c2158268d5"
},
"formuserId": "56841002eceefce22f455c7f",
"fromuser": "9674642375",
"touserId": "57130299e4b08c554c1092c7",
"touser": "dummyshop",
"message": "Creating Discussion",
"isMute": false,
"index": 4,
"createDate": {
"$date": "2016-06-01T10:27:02.574Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:02.574Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
}
],
"messageCount": 4,
"createDate": {
"$date": "2016-06-01T10:27:04.041Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:04.041Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
}
As this is a complex match on elements - $elemMatch cannot be used in this case,
so aggregation framework is a helper.
var match = {
$match : {
participants : /56d314a8e4b04d7f98cfd0c6/
}
}
var unwind = {
$unwind : "$messages"
}
var matchSecond = {
$match : {
$or : [{
"messages.touserId" : "56d314a8e4b04d7f98cfd0c6"
}, {
"messages.formuserId" : "56d314a8e4b04d7f98cfd0c6"
}
]
}
}
var projection = {
$project : {
_id : 0,
messages : 1
}
}
db.deb.aggregate([match, unwind, matchSecond, projection])
and output:
{
"messages" : {
"_id" : {
"oid" : "574eb874027520c2158268d2"
},
"formuserId" : "56841002eceefce22f455c7f",
"fromuser" : "9674642375",
"touserId" : "56d314a8e4b04d7f98cfd0c6",
"touser" : "debopam_r",
"message" : "Creating Discussion",
"isMute" : false,
"index" : 1.0,
"createDate" : {
"date" : "2016-06-01T10:27:00.500Z"
},
"lastModifiedDate" : {
"date" : "2016-06-01T10:27:00.501Z"
},
"createdBy" : "9674642375",
"lastModifiedBy" : "9674642375"
}
}
Given the following dataset:
[
{
"account_id" : "1111"
"task_id" : "aaaa",
"workweek" : "20",
"hours": "18"
},
{
"account_id" : "1111"
"task_id" : "aaaa",
"workweek" : "20",
"hours": "12"
},
{
"account_id" : "1111"
"task_id" : "aaaa",
"workweek" : "21",
"hours": "10"
},
{
"account_id" : "1111"
"task_id" : "bbbb",
"workweek" : "21",
"hours": "5"
},
{
"account_id" : "2222"
"task_id" : "cccc",
"workweek" : "21",
"hours": "15"
}
]
I'd like to group the documents and have the results in the following format:
[
{
"account_id": "1111",
"tasks": [
{
"task_id": "aaaa",
"workweeks": [
{
"workweek": "20",
"total_hours": "30"
},
{
"workweek": "21",
"total_hours": "10"
}
]
},
{
"task_id": "bbbb",
"workweeks": [
{
"workweek": "21",
"total_hours": "5"
}
]
}
]
},
{
"account_id": "2222",
"tasks": [
{
"task_id": "cccc",
"workweeks": [
{
"workweek": "21",
"total_hours": "15"
}
]
},
]
}
]
My broken aggregation code is the following:
db.tasks.aggregate([
{"$group": {
"_id": {
"account_id": "$account_id",
"task_id": "$task_id",
"workweek": "$workweek",
},
"total_hours": {$sum: "$hours"}
}},
{"$group": {
"_id": "$_id.account_id",
"tasks": {
"$push": {
"task_id": "$_id.task_id",
"workweeks": {
"$push": {
"workweek": "$_id.workweek",
"total_hours": "$total_hours"
}
}
}
}
}}
]);
I receive this error:
"errmsg" : "exception: invalid operator '$push'",
And I assume it is because I can only $push once per $group block.
Any ideas on how to achieve the desired result?
Please try with one additional (middleware) "group-by" step:
db.tasks.aggregate([
{"$group": {
"_id": {
"account_id": "$account_id",
"task_id": "$task_id",
"workweek": "$workweek",
},
"total_hours": {$sum: "$hours"}
}},
{"$group": {
"_id": {
"$_id.account_id",
"$_id.task_id"
},
"workweeks": {
"$push": {
"workweek": "$_id.workweek",
"total_hours": "$total_hours"
}
}
}},
{"$group": {
"_id": "$_id.account_id",
"tasks": {
"$push": {
"task_id": "$_id.task_id",
"workweeks": "$workweeks"
}
}
}}
]);