Mongodb 时间序列聚合中自上一条记录的时间差
我收集了不同演员制作的活动。我现在需要计算每个参与者发生的事件量x自上次事件发生以来的时间量 一个更具体的例子:由不同参与者创建的登录事件集合。应忽略自上次登录后8小时内发生的每个登录事件。假设我在下午2点登录,再在晚上11点登录,我们想要的计数是2。如果我在下午2点登录,再在下午5点登录,那就得算1 我真的没有看到使用聚合框架解决这个问题的可行方案。一个可能的解决方案是计算(并保存)每个记录上一个事件之间的时间。但我觉得应该有更好的解决办法 谁能给我指出正确的方向吗?没有发现任何与此类似的用例 如果我的问题不清楚,请告诉我Mongodb 时间序列聚合中自上一条记录的时间差,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我收集了不同演员制作的活动。我现在需要计算每个参与者发生的事件量x自上次事件发生以来的时间量 一个更具体的例子:由不同参与者创建的登录事件集合。应忽略自上次登录后8小时内发生的每个登录事件。假设我在下午2点登录,再在晚上11点登录,我们想要的计数是2。如果我在下午2点登录,再在下午5点登录,那就得算1 我真的没有看到使用聚合框架解决这个问题的可行方案。一个可能的解决方案是计算(并保存)每个记录上一个事件之间的时间。但我觉得应该有更好的解决办法 谁能给我指出正确的方向吗?没有发现任何与此类似的用例
编辑: 例如: 简化事件:
[{
_id: 1,
actor: X,
date: ISODate("2018-09-20T18:00:00.000Z")
},
{
_id: 2,
actor: X,
date: ISODate("2018-09-21T05:00:00.000Z") // 11 hours since previous
},
{
_id: 3,
actor: X,
date: ISODate("2018-09-21T07:00:00.000Z") // 2 hours since previous
},
{
_id: 4,
actor: Y,
date: ISODate("2018-09-21T06:00:00.000Z")
},
{
_id: 5,
actor: Y,
date: ISODate("2018-09-21T09:00:00.000Z") // 3 hours since previous
}]
预期产出:
[{
_id: X,
count: 2 // 3 events, but one is less than 8 hours since previous
},
{
_id: Y,
count: 1 // 2 events, but one is less than 8 hours since previous
}]
通过将不同文档中的值分组到数组中并对其进行迭代,可以比较这些值。在您的情况下,这可能是最简单的方法:
db.collection.aggregate([
// ensure order
{ $sort: { date: 1 } },
// get all dates per actor
{ $group: { _id: "$actor", dates: { $push: "$date" } } },
{ $addFields: {
// iterate dates
events: { $reduce: {
input: "$dates",
initialValue: { last: null, count: 1 },
// increment counter if difference is > than 8 * 60 * 60 * 1000 millis
in: { last: "$$this", count: { $add: [
"$$value.count",
{ $cond: [
{$gt: [ { $subtract: [ "$$this", "$$value.last" ] }, 28800000 ] },
1,
0
] }
] } }
} }
} },
{ $project: { count: "$events.count" } }
])
在大数据集上速度会很慢。在这种情况下,您可能需要在插入时预先聚合计数器。您可以发布样本数据和预期输出吗?@Akrion添加了一个简化的示例!这太棒了!问题是我们运行的是3.2,所以我不能使用addFields和reduce。我在我的开发环境中升级了我的mongo安装,并对其进行了测试,这种方法似乎可以产生所需的结果。这当然很慢,它需要在大约20mil+记录的集合上运行,但这不是问题,因为结果不需要是实时的。这将是我可以在生产中推动mongo升级的另一个原因。;)谢谢