mongoose - group collection data by multiple fields mongodb -
collection structure
order = new schema     index:          { type: number, unique: true }     number:         date     status:         { type: string, enum: ['success', 'failure'] }     created_at:     { type: date, default: date.now }     updated_at:     { type: date, default: date.now }   i need query returns me array of objects having data success count , failure count grouped date. ex-
orders = {               28-10-2016:{                success_count: 10,                 failure_count: 10               },               29-10-2016: {                success_count: 10,                 failure_count: 10               }           }      
with aggregation framework, result different "desired" output instead of having hash keys, array of objects _id key having value represents group field. instance, instead of
{     "28-10-2016":{         "success_count": 10,          "failure_count": 10     },     "29-10-2016": {         "success_count": 10,          "failure_count": 10     } }   you'd have better structure like
[     {         "_id": "28-10-2016",         "success_count": 10,          "failure_count": 10     },         "_id": "29-10-2016",         "success_count": 10,          "failure_count": 10     } ]   accomplishing above result require using $cond operator in $sum accumulator operator. $cond operator evaluate logical condition based on first argument (if) , returns second argument evaluation true (then) or third argument false (else). converts true/false logic 1 , 0 numerical values feed $sum respectively:
"success_count": {     "$sum": {         "$cond": [ { "$eq": [ "$status", "success" ] }, 1, 0 ]     } }   as resulting pipeline, 1 needs run aggregation operation uses $datetostring operator in _id key expression $group pipeline:
orders.aggregate([     {         "$group": {             "_id": {                 "$datetostring": {                      "format": "%y-%m-%d",                      "date": "$created_at"                  }             },             "success_count": {                 "$sum": {                     "$cond": [ { "$eq": [ "$status", "success" ] }, 1, 0 ]                 }             },             "failure_count": {                 "$sum": {                     "$cond": [ { "$eq": [ "$status", "failure" ] }, 1, 0 ]                 }             }         }     } ], function (err, orders){     if (err) throw err;     console.log(orders); })   however, there more flexible , better performant approach executes faster above, efficient data structure aggregation result follows schema example:
orders = [     {         "_id": "28-10-2016",         "counts": [             { "status": "success", "count": 10 },             { "status": "failure", "count": 10 }         ]     },     {         "_id": "29-10-2016",         "counts": [             { "status": "success", "count": 10 },             { "status": "failure", "count": 10 }         ]     } ]   then consider running alternative pipeline follows
orders.aggregate([     {          "$group": {             "_id": {                  "date":  {                     "$datetostring": {                          "format": "%y-%m-%d",                          "date": "$created_at"                      }                 },                 "status": { "$tolower": "$status" }             },             "count": { "$sum": 1 }         }     },     {          "$group": {             "_id": "$_id.date",             "counts": {                 "$push": {                     "status": "$_id.status",                     "count": "$count"                 }             }         }     } ], function (err, orders){     if (err) throw err;     console.log(orders); })      
Comments
Post a Comment