【原创】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查询模式中如何实现指数平滑法。