在MongoDB中按时聚合查询

时间:2015-02-01 18:26:34

标签: mongodb mongodb-query

我正在使用MongoDB Aggregate管道,对于我想做的大部分事情,它到目前为止都是完美的。

但是,我希望按时间和小组按个别日期,小时或分钟进行汇总。到目前为止,这是我的查询(在细粒度的情况下:

db.track.aggregate(
  [
    {$match: {event: /pricing/i}},
    {$unwind:"$userId"},
    {
      $group: {
        _id: {min: {$minute: "$timestamp"}},
        count: {$sum: 1}
      }
    }
  ]
)

这里显而易见的问题是它会将不同时间的分钟组合在一起。像这样:

{ "_id" : { "min" : 18 }, "count" : 8 }
{ "_id" : { "min" : 33 }, "count" : 18 }
{ "_id" : { "min" : 10 }, "count" : 6 }
{ "_id" : { "min" : 8 }, "count" : 2 }
{ "_id" : { "min" : 43 }, "count" : 2 }
{ "_id" : { "min" : 35 }, "count" : 6 }
{ "_id" : { "min" : 46 }, "count" : 2 }
{ "_id" : { "min" : 12 }, "count" : 4 }
{ "_id" : { "min" : 31 }, "count" : 4 }
{ "_id" : { "min" : 4 }, "count" : 14 }

我想在图表中使用该查询的结果。理想情况下,我希望得到类似的东西:

{ "_id" : { "time" : "14:04" }, "count" : 14 }

我的文档看起来像这样

{
    _id: ObjectId("54cd7b8f7e4515a41898faac"),
    userId: [
        "xp1ungmsrh3hbhjk7c2go45xxvh0uiaa9rel5",
        "a3c10b3c-3825-4b32-9a57-0e75b508d5bb"
    ],
    type: "track",
    timestamp: ISODate("2015-02-01T01:04:13.632Z"),
    event: "View Pricing Page"
}

我确信我错过了一些明显的东西,但是the doc并没有给我任何其他的东西。

任何人都可以指出我正确的方向吗?

2 个答案:

答案 0 :(得分:3)

Uae这个查询:

db.track.aggregate(
  [
    { $match: {event: /pricing/i} },
    { $unwind: "$userId" },
    {
      $group: 
      {
        _id: 
        {
            hour : { $hour : "$timestamp" },
            min: { $minute : "$timestamp" }
        },
        count: {$sum : 1}
      }
    },
    { $project : { _id : 0, count: 1, time : { $concat :[ {$substr:['$_id.hour', 0, 4]}, ':', {$substr:['$_id.min', 0, 4]}] }} },
  ]
)

示例输出:

{
    "result" : [ 
        {
            "count" : 2,
            "time" : "1:4"
        }
    ],
    "ok" : 1
}

如果您将最后一个$project更改为以下,则输出将完全按照您的提及

{ $project : { _id : 0, count: 1, '_id.time' : { $concat :[ {$substr:['$_id.hour', 0, 4]}, ':', {$substr:['$_id.min', 0, 4]}] }} },

输出:

{
    "result" : [ 
        {
            "_id" : {
                "time" : "1:4"
            },
            "count" : 2
        }
    ],
    "ok" : 1
}

答案 1 :(得分:0)

您需要在$group$project中使用组合_id的组合来创建时间。

db.track.aggregate(
  [
    {$match: {event: /pricing/i}},
    {$unwind:"$userId"},
    {
      $group: {
        _id: {min: {$minute: "$timestamp"}, hour: {$hour: "$timestamp"}},
        count: {$sum: 1}
      }
    },
    {$project: {time: {$concat:["$hour",":","$min"]}}}
  ]
)