Count events and insert string literal during aggregation

前端 未结 2 1929
滥情空心
滥情空心 2021-01-23 14:39

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

{
    \"_id\" : ObjectId(\"57fd7d00e4b         


        
相关标签:
2条回答
  • 2021-01-23 15:31

    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 } 
                } 
            }
        }
    }])
    
    0 讨论(0)
  • 2021-01-23 15:34

    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"
    }
    
    0 讨论(0)
提交回复
热议问题