Im trying to get multiple count values only from multiple documents in a collection which looks like this,( basically I want to get a count of how many are from the 4 directions)
{
"empno": 1500,
"province": "North"
}
{
"empno": 1600,
"province": "West"
}
early I found a solution and implemented following query;
([
{ "$facet": {
"N": [
{ "$match": { "province": "North" }},
{ "$count": "N" }
],
"E": [
{ "$match": { "province": "East" }},
{ "$count": "E" }
],
"S": [
{ "$match": { "province": "South" }},
{ "$count": "S" }
],
"W": [
{ "$match": { "province": "West" }},
{ "$count": "W" }
]
}},
{ "$project": {
"N": { "$arrayElemAt": ["$N.N", 0] },
"E": { "$arrayElemAt": ["$E.E", 0] },
"S": { "$arrayElemAt": ["$S.S", 0] },
"W": { "$arrayElemAt": ["$W.W", 0] },
}}
])
The output I get is
{ N: 1, W: 1 }
How can I get the values only like without the keys and also I want the blank fields that are empty to be with a 0. Like this;
{1, 0, 0, 1}
Facet
Query
group by null, is the thing that you needed to add to get the count
Test code here
db.collection.aggregate([
{
"$facet": {
"g0": [
{
"$match": {
"province": {
"$eq": "North"
}
}
},
{
"$group": {
"_id": null,
"count": {
"$sum": 1
}
}
},
{
"$project": {
"_id": 0
}
}
],
"g1": [
{
"$match": {
"province": {
"$eq": "East"
}
}
},
{
"$group": {
"_id": null,
"count": {
"$sum": 1
}
}
},
{
"$project": {
"_id": 0
}
}
],
"g2": [
{
"$match": {
"province": {
"$eq": "South"
}
}
},
{
"$group": {
"_id": null,
"count": {
"$sum": 1
}
}
},
{
"$project": {
"_id": 0
}
}
],
"g3": [
{
"$match": {
"province": {
"$eq": "West"
}
}
},
{
"$group": {
"_id": null,
"count": {
"$sum": 1
}
}
},
{
"$project": {
"_id": 0
}
}
]
}
},
{
"$set": {
"data": {
"$map": {
"input": {
"$objectToArray": "$$ROOT"
},
"in": {
"$cond": [
{
"$eq": [
"$$d.v",
[]
]
},
0,
{
"$let": {
"vars": {
"m": {
"$arrayElemAt": [
"$$d.v",
0
]
}
},
"in": "$$m.count"
}
}
]
},
"as": "d"
}
}
}
},
{
"$project": {
"data": 1
}
}
])
Group
Query
group is used instead of facet (facet is like 1 aggregation per field)
each group have its index (from the array), some indexes will be missing (because no documents exist)
add a zero-data field that has all indexes and count=0 (see bellow)
add to zero-data, the data found (the ones that existed in the collection,and we have groups for them) the rest keep the count=0
Test code here
db.collection.aggregate([
{
"$group": {
"_id": {
"$switch": {
"branches": [
{
"case": {
"$eq": [
"$province",
"North"
]
},
"then": {
"index": 0,
"province": "North"
}
},
{
"case": {
"$eq": [
"$province",
"East"
]
},
"then": {
"index": 1,
"province": "East"
}
},
{
"case": {
"$eq": [
"$province",
"South"
]
},
"then": {
"index": 2,
"province": "South"
}
},
{
"case": {
"$eq": [
"$province",
"West"
]
},
"then": {
"index": 3,
"province": "West"
}
}
],
"default": {
"index": 5
}
}
},
"count": {
"$sum": 1
}
}
},
{
"$group": {
"_id": null,
"data": {
"$push": {
"index": "$_id.index",
"province": "$province",
"count": "$count"
}
}
}
},
{
"$project": {
"_id": 0
}
},
{
"$set": {
"zero-data": [
{
"index": 0,
"count": 0
},
{
"index": 1,
"count": 0
},
{
"index": 2,
"count": 0
},
{
"index": 3,
"count": 0
}
]
}
},
{
"$set": {
"data": {
"$reduce": {
"input": "$zero-data",
"initialValue": [],
"in": {
"$let": {
"vars": {
"all_data": "$$value",
"d": "$$this"
},
"in": {
"$let": {
"vars": {
"found_data": {
"$filter": {
"input": "$data",
"cond": {
"$eq": [
"$$d.index",
"$$d1.index"
]
},
"as": "d1"
}
}
},
"in": {
"$concatArrays": [
"$$all_data",
[
{
"$cond": [
{
"$eq": [
"$$found_data",
[]
]
},
{
"index": "$$d.index",
"count": 0
},
{
"$arrayElemAt": [
"$$found_data",
0
]
}
]
}
]
]
}
}
}
}
}
}
}
}
},
{
"$project": {
"data": {
"$map": {
"input": "$data",
"in": "$$this.count"
}
}
}
}
])
Related
I have the following aggregation pipeline running in the latest version of mongoDB and pymongo:
[
{
"$project": {
"union": {
"$setUnion": [
"$query_a",
"$query_b"
]
}
}
},
{
"$unwind": "$union"
},
{
"$group": {
"_id": "$union.ID",
"date_a": {
"$addToSet": "$union.date_a"
},
"date_b": {
"$addToSet": "$union.date_b"
}
}
},
{
"$unwind": "$date_a"
},
{
"$unwind": "$date_b"
},
{
"$project": {
"_id": 1,
"date_a": "$date_a",
"date_b": "date_b",
"diff": {
"$subtract": [
{
"$toInt": "$date_b"
},
{
"$toInt": "$date_a"
}
]
}
}
},
{
"$match": {
"diff": {
"$gt": 0,
"$lte": 20
}
}
},
]
This gives the union of the 2 pipelines query_a and query_b. After this union I want to get an intersection on ID with the pipeline query_c: (query_a UNION query_b) INTERSECTION query_c.
For this playground example the desired output would be:
[
{
"ID": "c80ea2cb-3272-77ae-8f46-d95de600c5bf",
},
{
"ID": "cdbcc129-548a-9d51-895a-1538200664e6",
}
]
You could change and augment your pipeline a little to get your desired output.
db.collection.aggregate([
{
"$project": {
"union": {
// do the intersection here
"$filter": {
"input": {
"$setUnion": [
"$query_a",
"$query_b"
]
},
"as": "elem",
"cond": {
// only take IDs in query_c
"$in": ["$$elem.ID", "$query_c.ID"]
}
}
}
}
},
{
"$unwind": "$union"
},
{
"$group": {
"_id": "$union.ID",
"date_a": {
"$addToSet": "$union.date_a"
},
"date_b": {
"$addToSet": "$union.date_b"
}
}
},
{
"$unwind": "$date_a"
},
{
"$unwind": "$date_b"
},
{
"$project": {
"diff": {
"$subtract": [
{
"$toInt": "$date_b"
},
{
"$toInt": "$date_a"
}
]
}
}
},
{
"$match": {
"diff": {
"$gt": 0,
"$lte": 20
}
}
},
{ // get unique _id's
"$group": {
"_id": "$_id"
}
},
{ // rename _id to ID
"$project": {
"_id": 0,
"ID": "$_id"
}
}
])
Try it on mongoplayground.net.
You can do it with:
Updating first $project stage to also project an array of IDs from query_c.
Using $set as a second stage where you would filter out all items from the union of query_a and query_b, that does not have ID that's in query_c.
You can do it like this:
{
"$project": {
"union": {
"$setUnion": [
"$query_a",
"$query_b"
]
},
"query_c": {
"$map": {
"input": "$query_c",
"in": "$$this.ID"
}
}
}
},
{
"$set": {
"union": {
"$filter": {
"input": "$union",
"cond": {
"$in": [
"$$this.ID",
"$query_c"
]
}
}
}
}
},
The rest of your Aggregation pipeline can remain the same.
Working example
Employee has multiple employeeActions, the employeeActions data looks like this:
[
{
"email": "one#gmail.com",
"companyRegNo": 105,
"event": {
"created": ISODate("2022-09-16T06:42:04.387Z"),
"desc": "COMPLETED_APPLICATIONS",
"note": "Direct apply"
}
},
{
"email": "one#gmail.com",
"companyRegNo": 105,
"event": {
"created": ISODate("2022-09-20T06:42:42.761Z"),
"desc": "ASKED_TO_REVIEW",
}
},
{
"email": "two#gmail.com",
"companyRegNo": 227,
"event": {
"created": ISODate("2022-09-16T06:42:04.387Z"),
"desc": "COMPLETED_APPLICATIONS",
"note": "Direct apply",
}
},
{
"email": "two#gmail.com",
"companyRegNo": 227,
"event": {
"created": ISODate("2022-09-28T06:42:42.761Z"),
"desc": "ASKED_TO_REVIEW",
}
},
{
"email": "three#gmail.com",
"companyRegNo": 157,
"event": {
"created": ISODate("2022-09-16T06:42:04.387Z"),
"desc": "COMPLETED_APPLICATIONS",
"note": "Direct apply",
}
},
{
"email": "four#gmail.com",
"companyRegNo": 201,
"deleted": true,
"event": {
"created": ISODate("2022-09-15T06:42:42.761Z"),
"desc": "COMPLETED_APPLICATIONS",
}
},
]
I need to write an aggregation query to get all email ids where the employee action of the user
- Does not have an ASKED_TO_REVIEW event created before '2022-09-25'
- deleted is either false or does not exist
The out put should have only
{"email": "one#gmail.com"}
{"email": "three#gmail.com"}
The below match and project query did not work
db.collection.aggregate([
{
"$match": {
"$and": [
{
"deleted": {
"$ne": true
}
},
{
"$or": [
{
"$and": [
{
"event.name": {
"$eq": "ASKED_TO_REVIEW"
}
},
{
"event.created": {
"$lt": ISODate("2022-09-25")
}
}
]
},
{
"event.name": {
"$ne": "ASKED_TO_REVIEW"
}
}
]
}
]
}
},
{
"$project": {
"email": 1,
"_id": 0
}
}
])
How do i go about this?
You need to group the events by email and then apply your filtering logic to those groups, something like this:
db.collection.aggregate([
{
"$group": {
"_id": "$email",
"field": {
"$push": "$$ROOT"
}
}
},
{
"$match": {
$expr: {
"$eq": [
0,
{
"$size": {
"$filter": {
"input": "$field",
"as": "item",
"cond": {
"$or": [
{
"$and": [
{
"$eq": [
{
"$getField": {
"field": "desc",
"input": "$$item.event"
}
},
"ASKED_TO_REVIEW"
]
},
{
"$lt": [
{
"$getField": {
"field": "created",
"input": "$$item.event"
}
},
ISODate("2022-09-25")
]
}
]
},
{
"$eq": [
{
"$getField": {
"field": "deleted",
"input": "$$item"
}
},
true
]
}
]
}
}
}
}
]
}
}
},
{
"$project": {
email: "$_id",
"_id": 0
}
}
])
Playground link.
Figured out the working query. After grouping by email, $elemMatch needs to be used for the and condition between "event.desc" and "event.created"
db.collection.aggregate([
{
"$group": {
"_id": "$email",
"field": {
"$push": "$$ROOT"
}
}
},
{
"$match": {
"$and": [
{
"field.deleted": {
"$ne": true
}
},
{
"$or": [
{
"field": {
"$elemMatch": {
"event.desc": "ASKED_TO_REVIEW",
"event.created": {
"$lt": ISODate("2022-09-25")
}
}
}
},
{
"field.event.desc": {
"$ne": "ASKED_TO_REVIEW"
}
}
]
}
]
}
},
{
"$project": {
email: "$_id",
"_id": 0
}
}
])
Playground Link
There is a mongoDb collection, looks like this:
[
{
"_id": {
"$oid": "63110728d74738cdc48a7de0"
},
"listName": "list_name",
"alloweUidList": [
{
"uid": "prQUKkIxljVqbHlCKah7T1Rh7l22",
"role": "creator",
"boolId": 1,
"crDate": "2022-09-01 21:25",
"modDate": null
}
],
"offerModelList": [
{
"offerListenerEntity": {
"_id": "6311072ed74738cdc48a7de1",
"uid": "prQUKkIxljVqbHlCKah7T1Rh7l22",
"itemName": "sometehing",
"crDate": "2022-09-01 21:25",
"boolId": 1,
"modDate": null,
"imageColorIndex": 3,
"shoppingListId": "63110728d74738cdc48a7de0",
"checkFlag": 0,
"itemCount": 1
},
"offers": [
{
"id": "62fa7983b7f32cc089864a3b",
"itemId": 127382,
"itemName": "item_1",
"itemCleanName": "item_clean_name",
"imageUrl": "item.png",
"price": 10,
"measure": "measure",
"salesStart": "N.a",
"source": "source",
"runDate": "2022.08.15-14:11:15",
"shopName": "shop_name",
"isSales": 1,
"insertType": "automate",
"timeKey": "2022_08_15_18_51",
"imageColorIndex": 0,
"isSelectedFlag": 1,
"selectedBy": "not_selected",
"itemCount": 1
},
{
"id": "62fa7983b7f32cc089864a3b",
"itemId": 127382,
"itemName": "item_2",
"itemCleanName": "item_clean_name",
"imageUrl": "image.png",
"price": 20,
"measure": "measure",
"salesStart": "N.a",
"source": "source",
"runDate": "2022.08.15-14:11:15",
"shopName": "shop_name",
"isSales": 1,
"insertType": "automate",
"timeKey": "2022_08_15_18_51",
"imageColorIndex": 0,
"isSelectedFlag": 0,
"selectedBy": "not_selected",
"itemCount": 1
}
]
},
{
"offerListenerEntity": {
"_id": "6311a5c0d74738cdc48a7de2",
"uid": "prQUKkIxljVqbHlCKah7T1Rh7l22",
"itemName": "anything",
"crDate": "2022-09-02 08:42",
"boolId": 1,
"modDate": null,
"imageColorIndex": 1,
"shoppingListId": "63110728d74738cdc48a7de0",
"checkFlag": 0,
"itemCount": 2
},
"offers": []
}
],
"crDate": "2022-09-01 21:25",
"modDate": "2022-09-01 21:25",
"boolId": 1,
"imageColorIndex": 1
}
]
So it has an array, with a nested array.
I would like to filter out the entire item from the offerModelList array, if the offerModelList.offerListenerEntity.boolId == 0 It's working with this aggregate query:
[
{
"$match": {
"alloweUidList": {
"$elemMatch": {
"uid": "prQUKkIxljVqbHlCKah7T1Rh7l22",
"boolId": 1
}
},
"boolId": 1,
}
},
{
"$addFields": {
"offerModelList": {
"$filter": {
"input": "$offerModelList",
"as": "i",
"cond": {
"$eq": [
"$$i.offerListenerEntity.boolId",
1
]
}
}
}
},
}
]
The problem comes, when I try to filter out items from the offerModelList.offers array based on isSelectedFlag field.
I modified my query to this:
db.collection.aggregate([
{
"$match": {
"alloweUidList": {
"$elemMatch": {
"uid": "prQUKkIxljVqbHlCKah7T1Rh7l22",
"boolId": 1
}
},
"boolId": 1,
}
},
{
"$addFields": {
"offerModelList": {
"$filter": {
"input": "$offerModelList",
"as": "i",
"cond": {
"$eq": [
"$$i.offerListenerEntity.boolId",
1
]
}
}
}
},
},
{
"$addFields": {
"offerModelList.offers": {
"$filter": {
"input": "$offerModelList.offers",
"as": "x",
"cond": {
"$eq": [
"$$x.isSelectedFlag",
1
]
}
}
}
},
}
])
The problem is, it alwas return empty offers array.
Here comes an example: https://mongoplayground.net/p/kksRpoNKr1k in this specific case the offers array should cointains only 1 item.
Don't think that you are able to directly filter from offerModelList.offers.
Instead, for the last stage,
$set - Set offerModelList field.
1.1. $map - Iterate element in offerModelList array and return a new array.
1.1.1. $mergeObjects - Merge current iterated document with the document resulted from 1.1.1.1.
1.1.1.1. Document with offers array. Via $filter to filter the document(s) with isSelectedFlag: 1.
db.collection.aggregate([
{
"$match": {
"alloweUidList": {
"$elemMatch": {
"uid": "prQUKkIxljVqbHlCKah7T1Rh7l22",
"boolId": 1
}
},
"boolId": 1,
}
},
{
"$addFields": {
"offerModelList": {
"$filter": {
"input": "$offerModelList",
"as": "i",
"cond": {
"$eq": [
"$$i.offerListenerEntity.boolId",
1
]
}
}
}
},
},
{
"$set": {
"offerModelList": {
$map: {
input: "$offerModelList",
as: "offerModel",
in: {
$mergeObjects: [
"$$offerModel",
{
offers: {
$filter: {
input: "$$offerModel.offers",
as: "x",
cond: {
$eq: [
"$$x.isSelectedFlag",
1
]
}
}
}
}
]
}
}
}
}
}
])
Demo # Mongo Playground
Currently can't figure out why one pipeline works and the other doesn't. I got both pipelines from MongoDB charts and they both returned something and displaying charts on MongoDBCharts. However, when I use them in my code, only the first pipeline returns something. I used the same data for all cases. Any suggestions would be greatly appreciated!
The first one doesn't filter the last 30 days (hard coded by Mongo), both pipelines are copied from Mongodb charts and are not altered.
[
{
"$addFields": {
"trigger_time": {
"$convert": {
"input": "$trigger_time",
"to": "date",
"onError": null
}
}
}
},
{
"$match": {
"event_type": {
"$nin": [
null,
"",
"AC Lost",
"Device Lost",
"logged into Database",
"logged into Nexus Database",
"logged out of Nexus Database",
"Low Battery"
]
}
}
},
{
"$addFields": {
"trigger_time": {
"$cond": {
"if": {
"$eq": [
{
"$type": "$trigger_time"
},
"date"
]
},
"then": "$trigger_time",
"else": null
}
}
}
},
{
"$addFields": {
"__alias_0": {
"hours": {
"$hour": "$trigger_time"
}
}
}
},
{
"$group": {
"_id": {
"__alias_0": "$__alias_0"
},
"__alias_1": {
"$sum": 1
}
}
},
{
"$project": {
"_id": 0,
"__alias_0": "$_id.__alias_0",
"__alias_1": 1
}
},
{
"$project": {
"y": "$__alias_1",
"x": "$__alias_0",
"_id": 0
}
},
{
"$sort": {
"x.hours": 1
}
},
{
"$limit": 5000
}
]
The second one
[
{
"$addFields": {
"trigger_time": {
"$convert": {
"input": "$trigger_time",
"to": "date",
"onError": null
}
}
}
},
{
"$match": {
"event_type": {
"$nin": [
null,
"",
"AC Lost",
"Device Lost",
"logged into Database",
"logged into Nexus Database",
"logged out of Nexus Database",
"Low Battery"
]
},
"trigger_time": {
"$gte": {
"$date": "2021-03-29T08:35:47.804Z"
}
}
}
},
{
"$addFields": {
"trigger_time": {
"$cond": {
"if": {
"$eq": [
{
"$type": "$trigger_time"
},
"date"
]
},
"then": "$trigger_time",
"else": null
}
}
}
},
{
"$addFields": {
"__alias_0": {
"hours": {
"$hour": "$trigger_time"
}
}
}
},
{
"$group": {
"_id": {
"__alias_0": "$__alias_0"
},
"__alias_1": {
"$sum": 1
}
}
},
{
"$project": {
"_id": 0,
"__alias_0": "$_id.__alias_0",
"__alias_1": 1
}
},
{
"$project": {
"y": "$__alias_1",
"x": "$__alias_0",
"_id": 0
}
},
{
"$sort": {
"x.hours": 1
}
},
{
"$limit": 5000
}
]
I end up solving my own problem. After a bit of digging and asking.
Node.js does some funny things with Mongodb when it comes to using '$date', that's why the pipeline didn't work.
The resolve was to remove '$date' and pass in a date object. For my case,
"trigger_time": {
"$gte": new Date("2021-03-29T08:35:47.804Z")
}
I have the following MongoDB aggregation query which groups by IDC, type and cluster - which works perfectly.
I would like to additionally group "environment", inside this existing grouping. Please see my query below, my existing output, and what I would like to see (desired output).
If you have any questions or wish to see the source (I didn't think it was necessary, as it would take up room on the question, then please comment).
Thanks
Example Source (around 1000 documents):
{
"_id":"55d5dc40281077b6d8af1bfa",
"hostname":"1",
"domain":"domain",
"description":"VMWare ESXi 5",
"cluster":1,
"type":"Physical",
"os":"EXSi",
"idc":"AMS",
"environment":"DR",
"deviceclass":"host",
"cores":64,
"memory":256,
"clusters":0,
"customer":"MnS",
"mounts":[],
"roles":["ESX-HOST"],
"ipset":{"backnet":"1"},
"frontnet":[],
"created":"2015-09-28T11:12:36.526Z"
}
Query:
Machine.aggregate([
{ "$match": {
"idc": req.query.idc, "customer": req.query.customer}
} ,
{ "$group": {
"_id": {
"cluster": "$cluster",
"idc":"$idc",
"type": "$type"
},
"SumCores": { "$sum":"$cores" },
"SumMemory": { "$sum":"$memory" }
}},
{ "$group": {
"_id": {
"cluster": "$_id.cluster",
"idc": "$_id.idc"
},
"data": {
"$push": {
"type": "$_id.type",
"SumCores": "$SumCores",
"SumMemory": "$SumMemory"
}
}
}},
{ "$project": {
"Physical": {
"$setDifference": [
{ "$map": {
"input": "$data",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.type", "Physical" ] },
{
"SumCores": "$$el.SumCores",
"SumMemory": "$$el.SumMemory"
},
false
]
}
}},
[false]
]
},
"Virtual": {
"$setDifference": [
{ "$map": {
"input": "$data",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.type", "Virtual" ] },
{
"SumCores": "$$el.SumCores",
"SumMemory": "$$el.SumMemory"
},
false
]
}
}},
[false]
]
}
}},
{ "$unwind": "$Physical" },
{ "$unwind": "$Virtual"},
{ "$sort" : { "_id.idc": -1, "_id.cluster": 1 } }
]);
Which gives me the following output:
{
"_id" : {
"cluster" : 1,
"idc" : "LH5"
},
"Physical" : {
"SumCores" : 192,
"SumMemory" : 768
},
"Virtual" : {
"SumCores" : 112,
"SumMemory" : 384
}
}
My desired output is:
[
{
"_id": {
"cluster": 1,
"idc": "LH8"
},
"Physical": [
{
"environment": "DR",
"SumCores": 256,
"SumMemory": 1024
},
{
"environment": "PROD",
"SumCores": 256,
"SumMemory": 1024
}
],
"Virtual": [
{
"environment": "DR",
"SumCores": 232,
"SumMemory": 469
},
{
"environment": "PROD",
"SumCores": 232,
"SumMemory": 469
}
]
}
]
Essentially, I want to group the sums based on the environment
Very much as in your initial query ( actually written by myself ), all you really need to do is add in that field detail to the initial _id of $group and then carry that through into the subsequent array entries:
Machine.aggregate([
{ "$match": {
"idc": req.query.idc, "customer": req.query.customer}
} ,
{ "$group": {
"_id": {
"cluster": "$cluster",
"idc":"$idc",
"type": "$type",
"environment": "$environment"
},
"SumCores": { "$sum":"$cores" },
"SumMemory": { "$sum":"$memory" }
}},
{ "$group": {
"_id": {
"cluster": "$_id.cluster",
"idc": "$_id.idc"
},
"data": {
"$push": {
"type": "$_id.type",
"environment": "$_id.environment",
"SumCores": "$SumCores",
"SumMemory": "$SumMemory"
}
}
}},
{ "$project": {
"Physical": {
"$setDifference": [
{ "$map": {
"input": "$data",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.type", "Physical" ] },
{
"environment": "$$el.environment",
"SumCores": "$$el.SumCores",
"SumMemory": "$$el.SumMemory"
},
false
]
}
}},
[false]
]
},
"Virtual": {
"$setDifference": [
{ "$map": {
"input": "$data",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.type", "Virtual" ] },
{
"environment": "$$el.environment",
"SumCores": "$$el.SumCores",
"SumMemory": "$$el.SumMemory"
},
false
]
}
}},
[false]
]
}
}},
{ "$unwind": "$Physical" },
{ "$unwind": "$Virtual"},
{ "$sort" : { "_id.idc": -1, "_id.cluster": 1 } }
]);
But you also "really" should be using the query form I recommended you did in the first place, since it is clear that all you want to do is diplay this in a template, and looping array content should be very simple:
Machine.aggregate([
{ "$match": {
"idc": req.query.idc, "customer": req.query.customer}
} ,
{ "$group": {
"_id": {
"cluster": "$cluster",
"idc":"$idc",
"type": "$type",
"environment": "$environment"
},
"SumCores": { "$sum":"$cores" },
"SumMemory": { "$sum":"$memory" }
}},
{ "$group": {
"_id": {
"cluster": "$_id.cluster",
"idc": "$_id.idc"
},
"data": {
"$push": {
"type": "$_id.type",
"environment": "$_id.environment",
"SumCores": "$SumCores",
"SumMemory": "$SumMemory"
}
}
}},
{ "$sort" : { "_id.idc": -1, "_id.cluster": 1 } }
]);