Count events and insert string literal during aggregation

我的未来我决定 提交于 2019-12-31 04:04:29

问题


I have large collection of documents which represent some kind of events. Collection contains events for different userId.

{
    "_id" : ObjectId("57fd7d00e4b011cafdb90d22"),
    "userId" : "123123123",
    "userType" : "mobile",
    "event_type" : "clicked_ok",
    "country" : "US",
    "timestamp" : ISODate("2016-10-12T00:00:00.308Z")
}
{
    "_id" : ObjectId("57fd7d00e4b011cafdb90d22"),
    "userId" : "123123123",
    "userType" : "mobile",
    "event_type" : "clicked_cancel",
    "country" : "US",
    "timestamp" : ISODate("2016-10-12T00:00:00.308Z")
}

At midnight I need to run aggregation for all documents for the previous day. Documents need to aggregated in the way so I could get number of different events for particular userId.

{
    "userId" : "123123123",
    "userType" : "mobile",
    "country" : "US",
    "clicked_ok" : 23,
    "send_message" : 14,
    "clicked_cancel" : 100,
    "date" : "2016-11-24",
}

During aggregation I need to perform two things:

  1. calculate number of events for particular userId
  2. add "date" text fields with date

Any help is greatly appreciated! :)


回答1:


you can do this with aggregation like this :

db.user.aggregate([
   {
      $match:{
         $and:[
            {
               timestamp:{
                  $gte: ISODate("2016-10-12T00:00:00.000Z")
               }
            },
            {
               timestamp:{
                  $lt: ISODate("2016-10-13T00:00:00.000Z")
               }
            }
         ]
      }
   },
   {
      $group:{
         _id:"$userId",
         timestamp:{
            $first:"$timestamp"
         },
         send_message:{
            $sum:{
               $cond:[
                  {
                     $eq:[
                        "$event_type",
                        "send_message"
                     ]
                  },
                  1,
                  0
               ]
            }
         },
         clicked_cancel:{
            $sum:{
               $cond:[
                  {
                     $eq:[
                        "$event_type",
                        "clicked_cancel"
                     ]
                  },
                  1,
                  0
               ]
            }
         },
         clicked_ok:{
            $sum:{
               $cond:[
                  {
                     $eq:[
                        "$event_type",
                        "clicked_ok"
                     ]
                  },
                  1,
                  0
               ]
            }
         }
      }
   },
   {
      $project:{
         date:{
            $dateToString:{
               format:"%Y-%m-%d",
               date:"$timestamp"
            }
         },
         userId:1,
         clicked_cancel:1,
         send_message:1,
         clicked_ok:1
      }
   }
])

explanation:

keep only document for a specific day in $match stage

group doc by userId and count occurrences for each event in $group stage

finally format the timestamp field into yyyy_MM-dd format in $project stage

for the data you provided, this will output

{
   "_id":"123123123",
   "send_message":0,
   "clicked_cancel":1,
   "clicked_ok":1,
   "date":"2016-10-12"
}



回答2:


Check the following query

db.sandbox.aggregate([{ 
    $group: {
        _id: {
            userId: "$userId", 
            date: {
                $dateToString: { format: "%Y-%m-%d", date: "$timestamp" }} 
            }, 
        send_message: { 
            $sum: { 
                $cond: { if: { $eq: ["$event_type", "send_message"] }, then: 1, else: 0 } } 
            },
        clicked_cancel: { 
            $sum: { 
                $cond: { if: { $eq: ["$event_type", "clicked_cancel"] }, then: 1, else: 0 } 
            } 
        },
        clicked_ok: { 
            $sum: { 
                $cond: { if: { $eq: ["$event_type", "clicked_ok"] }, then: 1, else: 0 } 
            } 
        }
    }
}])


来源:https://stackoverflow.com/questions/40831269/count-events-and-insert-string-literal-during-aggregation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!