在聚合期间计算事件并插入字符串文字

时间:2016-11-27 16:39:46

标签: mongodb mongodb-query aggregation-framework

我有很多代表某种事件的文件。集合包含不同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")
}

午夜我需要为前一天的所有文件运行聚合。文档需要以这种方式聚合,以便我可以获得特定userId的不同事件的数量。

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

在聚合期间,我需要执行两项任务:

  1. 计算特定userId的事件数
  2. 添加"日期"带日期的文字字段
  3. 非常感谢任何帮助! :)

2 个答案:

答案 0 :(得分:1)

检查以下查询

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 } 
            } 
        }
    }
}])

答案 1 :(得分:1)

你可以用这样的聚合来做到这一点:

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
      }
   }
])

解释:

仅保留 $ match 阶段

中特定日期的文档

按用户ID分组doc并计算 $ group 阶段中每个事件的出现次数

最后在 $ project 阶段将时间戳字段格式化为 yyyy_MM-dd 格式

对于您提供的数据,将输出

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