MongoDB聚合框架,用于对时间范围内发生的文档进行分组?

MongoDB聚合框架,用于对时间范围内发生的文档进行分组?,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,示例文档 [ {time: ISODate('2015-07-04T03:12:00.000Z')}, {time: ISODate('2015-07-04T03:15:00.000Z')}, {time: ISODate('2015-07-04T04:59:00.000Z')}, {time: ISODate('2015-07-04T05:01:00.000Z')} ] 预期产量 [ { '_id': 'groupA', 'count': 2, '

示例文档

[
  {time: ISODate('2015-07-04T03:12:00.000Z')},
  {time: ISODate('2015-07-04T03:15:00.000Z')},
  {time: ISODate('2015-07-04T04:59:00.000Z')},
  {time: ISODate('2015-07-04T05:01:00.000Z')}
]
预期产量

[
  {
    '_id': 'groupA',
    'count': 2,
    'min': ISODate('2015-07-04T03:12:00.000Z'),
    'max': ISODate('2015-07-04T03:15:00.000Z')
  },
  {
    '_id': 'groupB',
    'count': 2,
    'min': ISODate('2015-07-04T04:59:00.000Z'),
    'max': ISODate('2015-07-04T05:01:00.000Z')
  }
]
是否可以使用MongoDB聚合框架对在某个时间范围内发生的文档进行分组?如何对$group调用进行建模,以将示例文档转换为预期输出


我曾尝试将时间转换为毫秒,然后使用模创建时间桶,但这会产生具有任意边界的桶。例如,2015-07-04T04:59:00.000Z将与2015-07-04T05:01:00.000Z处于一个单独的组中,即使它们应该分组在一起。

根据您想要分组的时间范围,您可能可以使用MongoDB实现这一点

使用这些函数,您可以对日期/时间的单独元素进行投影或分组,并在需要时进行组合

使用您的示例数据,以下聚合管道将按小时对您的输入进行分组:

{ '$group' : {
    '_id' : {
        'document_day' : { '$dayOfMonth' : '$time' },
        'document_month' : { '$month' : '$time'},
        'document_year' : { '$year' : '$time'},
        'document_hour' : { '$hour' : '$time' }
        },
    'count' : { '$sum' : 1 },
    'min' : { '$min' : '$time'},
    'max' : { '$max' : '$time'}
    }
},
{
    '$project' : {
        '_id' : 0,
        'count' : '$count',
        'min' : '$min',
        'max' : '$max'
    }

}
并将为您提供以下结果:

{ 
  "count" : 1, 
  "min" : ISODate("2015-07-04T05:01:00Z"), 
  "max" : ISODate("2015-07-04T05:01:00Z") 
},
{ 
  "count" : 1, 
  "min" : ISODate("2015-07-04T04:59:00Z"), 
  "max" : ISODate("2015-07-04T04:59:00Z") 
},
{ 
  "count" : 2, 
  "min" : ISODate("2015-07-04T03:12:00Z"), 
  "max" : ISODate("2015-07-04T03:15:00Z") 
}

不确定这是否正是您想要的,但我没有必要的代表留下评论。

根据您想要分组的时间范围,您可以使用MongoDB的

使用这些函数,您可以对日期/时间的单独元素进行投影或分组,并在需要时进行组合

使用您的示例数据,以下聚合管道将按小时对您的输入进行分组:

{ '$group' : {
    '_id' : {
        'document_day' : { '$dayOfMonth' : '$time' },
        'document_month' : { '$month' : '$time'},
        'document_year' : { '$year' : '$time'},
        'document_hour' : { '$hour' : '$time' }
        },
    'count' : { '$sum' : 1 },
    'min' : { '$min' : '$time'},
    'max' : { '$max' : '$time'}
    }
},
{
    '$project' : {
        '_id' : 0,
        'count' : '$count',
        'min' : '$min',
        'max' : '$max'
    }

}
并将为您提供以下结果:

{ 
  "count" : 1, 
  "min" : ISODate("2015-07-04T05:01:00Z"), 
  "max" : ISODate("2015-07-04T05:01:00Z") 
},
{ 
  "count" : 1, 
  "min" : ISODate("2015-07-04T04:59:00Z"), 
  "max" : ISODate("2015-07-04T04:59:00Z") 
},
{ 
  "count" : 2, 
  "min" : ISODate("2015-07-04T03:12:00Z"), 
  "max" : ISODate("2015-07-04T03:15:00Z") 
}

不确定这是否正是您想要的,但我没有必要的代表将此作为评论。

我将执行以下操作:

  • 给你的约会点数排序[12:58,13:01,13:45,13:49]
  • 取日期点的第一个差值[0分钟、3分钟、44分钟、4分钟]
  • 定义一个相对阈值(例如,1个标准偏差),用于将不同的日期点分成组[[12:58,13:01],[13:45,13:49]]

  • 我会这样做:

  • 给你的约会点数排序[12:58,13:01,13:45,13:49]
  • 取日期点的第一个差值[0分钟、3分钟、44分钟、4分钟]
  • 定义一个相对阈值(例如,1个标准偏差),用于将不同的日期点分成组[[12:58,13:01],[13:45,13:49]]

  • 问题缺少的是对原因的解释?这样的时间应该组合在一起。清楚的是,它们实际上是在不同的时间,我们通常不按“最近的桶”,而是总是按“四舍五入”的间隔。当然,除非你想有逻辑,比如前5分钟,后5分钟,然后每隔10分钟继续。但是如果你不能解释原因!,那么我真的不明白你在说什么。这些例子甚至没有包含预期输出中的所有内容,很难帮助你。请给出至少完整的示例文档。我每天收集2000个文档。这些文件是描述通常持续20到30分钟的较长事件的单独观察结果。我不知道这件事在白天什么时候发生,也不知道时间如何与小时、半小时或诸如此类的时间排成一行。我试图使用聚合创建一个汇总视图,该视图提供每天4到5次事件的概览,而不是2000次单独观察。groupA和groupB标记任意字符串以表示两个单独的组,没有任何意义,也不是从任何输入数据派生的。问题缺少的是对为什么?这样的时间应该组合在一起。清楚的是,它们实际上是在不同的时间,我们通常不按“最近的桶”,而是总是按“四舍五入”的间隔。当然,除非你想有逻辑,比如前5分钟,后5分钟,然后每隔10分钟继续。但是如果你不能解释原因!,那么我真的不明白你在说什么。这些例子甚至没有包含预期输出中的所有内容,很难帮助你。请给出至少完整的示例文档。我每天收集2000个文档。这些文件是描述通常持续20到30分钟的较长事件的单独观察结果。我不知道这件事在白天什么时候发生,也不知道时间如何与小时、半小时或诸如此类的时间排成一行。我试图使用聚合创建一个汇总视图,该视图提供每天4到5个事件的概览,而不是2000个单独的观察结果。groupA和groupB标记任意字符串以表示两个单独的组,没有任何意义,也不是从任何输入数据派生的。如果仔细阅读问题,OP看起来确实要了解日期聚合运算符,甚至尝试了其他方法,可以使用数学运算符对日期值进行有效舍入。但他们的例子很清楚(即使问题中为什么?的目的不是),因为期望“4:59”条目也与“5:01”条目处于同一分组中。正如他们的问题所述,这当然会把他们分成不同的小组。因此,“全面”阅读问题很重要。如果你仔细阅读问题,OP似乎知道日期聚合运算符,甚至尝试了其他方法,通过使用数学运算符有效地舍入日期值。但他们的例子很清楚(即使问题中为什么?的目的不是),因为期望“4:59”条目也与“5:01”条目处于同一分组中。正如他们的问题所述,这当然会把他们分成不同的小组。因此,“全面”阅读所提出的问题很重要。在聚合框架中如何做到这一点?我可以在聚合框架之外解决这个问题。我正在尝试通过一个简单的聚合管道看看这是否可行。在聚合框架中如何做到这一点?我可以在聚合框架之外解决问题W