MongoDB聚合,以获取时间跨度内的事件以及前一个事件

yhuiod9q  于 2023-03-01  发布在  Go
关注(0)|答案(1)|浏览(138)

我有时间序列数据作为随机时间的事件。它们不是持续的指标,而是事件。“这个设备上线了。”“这个设备下线了。”
我需要报告某个时间范围内的 * 实际 * 转换数。因为偶尔会有相同状态的事件,例如一行中有两个“联机”事件,所以我需要用该时间范围之前的状态“播种”数据。如果我的时间范围内有事件,我需要将它们与该时间范围之前的状态进行比较,以确定是否发生了实际更改。
我已经有了移除相同状态事件的聚合阶段。
有没有一种方法可以在不编写两个查询的情况下将“最近的、先前的事件”添加到管道中的数据中?$facet阶段完全破坏了性能。
对于“previous”,我目前正在一个单独的查询中尝试类似这样的操作,但是对于数百万条记录来说,速度非常慢:

// Get the latest event before a given date
db.devicemetrics.aggregate([
  {
    $match: {
      'device.someMetadata': '70b28808-da2b-4623-ad83-6cba3b20b774',
      time: {
        $lt: ISODate('2023-01-18T07:00:00.000Z'),
      },
      someValue: { $ne: null },
    },
  },
  {
    $group: {
      _id: '$device._id',
      lastEvent: { $last: '$$ROOT' },
    },
  },
  {
    $replaceRoot: { newRoot: '$lastEvent' },
  }
]);
3df52oht

3df52oht1#

您正在寻找类似于SQL中的LAG窗口函数的东西。Mongo为此提供了$setWindowFields,并结合了$shift Order操作符。
不确定集合中的字段,但这应该会给予您有所了解。

{
   $setWindowFields: {
      partitionBy: "$device._id", //1. partition the data based on $device._id
      sortBy: { time: 1 },        //2. within each partition, sort based on $time
      output: {
         "shiftedEvent": {        //3. add a new field shiftedEvent to each document
            $shift: {
               output: "$event",  //4. whose value is previous $event
               by: -1
            }
         }
      }
   }
}

然后,您可以比较event和shiftedEvent字段。

相关问题