按名称分组时分割成时间桶

时间:2017-05-26 02:28:22

标签: mongodb mongodb-query aggregation-framework

我有一个MongoDB集合,division_entry。

我希望按标签过滤,然后按时间和不同的唯一值进行操作。 最后,我希望在给定的时间跨度内具有唯一的唯一值。

目前,我必须填写代码并按时间跨度拨打电话。这导致了太多的电话。 礼物 -

  

db.division_entry.aggregate([{$ match:{$ and:[{" division.label":   " ABCD"},{"时间戳" :{$ gt:1495448249635,$ lt:1495448249641}}   ]}},{$ group:{_ id:" $ unique"}},{$ count:" value" }])

非常感谢对实际结果的帮助。

编辑: 更多细节:

{
            "_id" : "1",
            "timestamp" : NumberLong("1495448249640"),
            "unique" : "One",
            "division" : [
                    {
                            "label" : "ABCD"
                    }
            ]
    }
    {
            "_id" : "3",
            "timestamp" : NumberLong("1495448249636"),
            "unique" : "Two",
            "division" : [
                    {
                            "label" : "ABCD"
                    }
            ]
    }
    {
            "_id" : "2",
            "timestamp" : NumberLong("1495448249650"),
            "unique" : "Two",
            "division" : [
                    {
                            "label" : "ABCD"
                    }
            ]
    }

db.division_entry.aggregate([{ $match : { $and : [ { "division.label": "ABCD"}, { "timestamp" : { $gt: 1495448249635, $lt: 1495448249651 }} ] } } , {$group : { _id : "$unique"} }])
         { "_id" : "Two" }
         { "_id" : "One" }

db.division_entry.aggregate([{ $match : { $and : [ { "division.label" : "ABCD"}, { "timestamp" : { $gt: 1495448249635, $lt: 1495448249651 } } ] } } , {$group : { _id : "$unique"} } , {$count : "value" }])
        { "value" : 2 }

这是针对特定时间范围完成的,该时间范围已在匹配查询中指定。假设我想要一天的分钟数据,我将不得不拨打1440个这样的电话,在每个电话中,时间戳范围将覆盖一分钟。

我希望获得帮助,并为该领域寻找独特的价值观。&34; unique"同时进行。

2 个答案:

答案 0 :(得分:1)

对于常规间隔,最好的做法是执行一些“日期数学运算”,将文档中的当前"timestamp"值四舍五入到用于分组的公共区间值。执行此操作的最佳方法是使用标准匹配减去应用于所需间隔的毫秒值的模数(余数)。

在聚合框架中,我们使用$subtract$mod来提供复合键的一方以及"unique"键中的当前文档_id字段值{ {3}}:

db.division_entry.aggregate([
  // Sanely restrict to a range of dates to analyse - here is one day
  { "$match": { 
    "timestamp": { "$gte": 1495670400000, "$lt": 1495756800000 }
  }},

  // Group by interval - example of 1 hour ( 1000ms * 60sec * 60min )
  { "$group": {
    "_id": {
      "time": {
        "$subtract": [
          "$timestamp",
          { "$mod": [ "$timestamp", ( 1000 * 60 * 60 ) ] }
        ]
      },
      "unique": "$unique"
    },
    "count": { "$sum": 1 }
  }}
])

因此,对于不同的时间间隔,您需要的只是提供所需时间间隔的数学运算:

  • 1分钟(1000 * 60)
  • 1小时(1000 * 60 * 60)
  • 1天(1000 * 60 * 60 * 24)

仅供参考,有一个新引入的$group运算符,但它的目的是为了“ 统一的”切点“。例如0-5分钟,6-20分钟,20-50分钟和超过50分钟作为示例用例。

对于任何“统一”,基于数学的方法是最有效的方法。

答案 1 :(得分:0)

这是基于Neil的回答。

我还想要的是不同的时间间隔和它们中唯一的uuids数量。他提供的答案为每个唯一的uuid提供了在时间间隔内出现的次数,即q。

db.divisive_entry.aggregate([
  { "$match": { 
    "timestamp": { "$gte": 1395448852351, "$lt": 1497428775000 }
  }},

  { "$group": {
    "_id": {
      "time": {
        "$subtract": [
          "$timestamp",
          { "$mod": [ "$timestamp", ( 1000 * 60 * 60 ) ] }
        ]
      },
      "unique": "$unique"
    },
  }},

  { "$group": 
    {
        "_id": "$_id.time",
        "count" : { "$sum": 1 }
    }
  }
])