【原创】StreamInsight查询系列(二十二)——查询模式之持续更新

上篇文章介绍了查询模式中如何使用地理数据,这篇博文将介绍StreamInsight中如何进行持续更新。

测试数据准备

为了方便测试查询,我们首先准备一个静态的测试数据源:

var sourceData = new []
{
    new { Value = 12, Status = 0, TimeStamp = DateTime.Parse("10/23/2009 9:00:00 AM") },
    new { Value = 15, Status = 0, TimeStamp = DateTime.Parse("10/23/2009 10:10:00 AM") },
    new { Value = 2,  Status = 1, TimeStamp = DateTime.Parse("10/23/2009 11:12:00 AM") },
    new { Value = 48, Status = 0, TimeStamp = DateTime.Parse("10/23/2009 12:13:00 PM") },
    new { Value = 34, Status = 1, TimeStamp = DateTime.Parse("10/23/2009 1:14:00 PM") },
    new { Value = 31, Status = 0, TimeStamp = DateTime.Parse("10/23/2009 2:15:00 PM") },
    new { Value = 33, Status = 1, TimeStamp = DateTime.Parse("10/23/2009 3:20:00 PM") },
    new { Value = 10, Status = 0, TimeStamp = DateTime.Parse("10/23/2009 4:30:00 PM") },
    new { Value = 19, Status = 0, TimeStamp = DateTime.Parse("10/23/2009 5:35:00 PM") },
};

接下去将上述数据源转变为点类型复杂事件流:

var inputStream = sourceData.ToPointStream(Application, ev =>
    PointEvent.CreateInsert(ev.TimeStamp.ToLocalTime(), ev),
    AdvanceTimeSettings.StrictlyIncreasingStartTime);

持续更新

问题1:怎样在一系列事件上执行持续的聚合操作(如在一天的时间内,不断的更新统计结果)?

首先将事件流中的事件生命周期延伸至一天结束,然后使用快照窗口统计结果,如下:

// 考虑到衡量时间的基本单位是刻度,这里首先将事件时间转换为刻度数,并使用基本的算术运算修改事件持续时间
var running = from win in inputStream
                  // 将每个事件的结束时间更改为第二天的凌晨12点前的最后一刻
                  .AlterEventDuration(e => TimeSpan.FromTicks(
                      TimeSpan.TicksPerDay - (e.StartTime.Ticks % TimeSpan.TicksPerDay)))
                  // 使用快照窗口对每一个新的事件进行更新
                  .SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
              select new 
              { 
                  // 对接受到的事件值进行求和
                  runningTotal = win.Sum(e => e.Value) 
              };

结果如下:

问题2:怎样在一天里,每隔2小时的不断计算更新聚合操作结果?

比较简单的做法可以在问题1的结果事件流上进行跳跃统计,实现如下:

var result = from win in running.HoppingWindow(
     TimeSpan.FromTicks(1), TimeSpan.FromHours(2),
     HoppingWindowOutputPolicy.ClipToWindowEnd)
 select new
 {
     // 窗口仅用来显示每2小时候的一个事件点
     CountSoFar = win.Sum(e => e.runningTotal)
 };

注意TimeSpan.FromTicks(1),这是为了结果一次只有一个事件点。运行结果如下:

下一篇将介绍StreamInsight查询模式中如何实现指数平滑法。

posted @ 2011-09-18 19:14  StreamInsight  阅读(978)  评论(0编辑  收藏  举报