【原创】StreamInsight查询系列(十五)——查询模式之窗口比率
上篇文章介绍了查询模式中相异计数部分,这篇博文将介绍窗口比率,即找出某类事件占事件总数的百分比。
测试数据准备
为了方便测试查询,我们首先准备一个静态的测试数据源:
var sourceData = new[] { new { SourceId = "A", Value = 22, Status = "SUCCESS", TimeStamp = DateTime.Parse("10/23/2009 4:12:00 PM") }, new { SourceId = "A", Value = 24, Status = "FAIL", TimeStamp = DateTime.Parse("10/23/2009 4:12:01 PM") }, new { SourceId = "A", Value = 31, Status = "SUCCESS", TimeStamp = DateTime.Parse("10/23/2009 4:12:03 PM") }, new { SourceId = "A", Value = 67, Status = "FAIL", TimeStamp = DateTime.Parse("10/23/2009 4:13:00 PM") }, new { SourceId = "A", Value = 54, Status = "FAIL", TimeStamp = DateTime.Parse("10/23/2009 4:13:02 PM") }, new { SourceId = "A", Value = 50, Status = "SUCCESS", TimeStamp = DateTime.Parse("10/23/2009 4:14:00 PM") }, new { SourceId = "A", Value = 87, Status = "FAIL", TimeStamp = DateTime.Parse("10/23/2009 4:14:01 PM") }, };
接下去将dataWithDups转变为点类型复杂事件流:
var source = sourceData.ToPointStream(Application, ev => PointEvent.CreateInsert(ev.TimeStamp.ToLocalTime(), ev), AdvanceTimeSettings.StrictlyIncreasingStartTime);
窗口比率
问题:怎样计算过去2分钟内满足条件的某类事件占事件总数的百分比?
方法一:
- 统计每个时间窗口内的事件总数;
- 统计每个时间窗口内满足某个条件的事件总数;
- 联接结果并计算百分比。
下面分别实现这3个部分的查询。
第1步:统计2分钟窗口内的事件总数:
var countAllEvents = from win in source.HoppingWindow( TimeSpan.FromMinutes(2), TimeSpan.FromMinutes(1), HoppingWindowOutputPolicy.ClipToWindowEnd) select new { Count = win.Count() };
第2步:统计2分钟窗口内状态为"SUCCESS"的事件总数:
var countSuccessfulEvents = from win in source.Where(e => e.Status == "SUCCESS").HoppingWindow( TimeSpan.FromMinutes(2), TimeSpan.FromMinutes(1), HoppingWindowOutputPolicy.ClipToWindowEnd) select new { Count = win.Count() };
第3步:计算成功事件占事件总数的比率:
(注:在这个例子中,由于跳跃窗口重叠的部分较多,我们将间隔事件流转换为点事件类型以使得对于每个时间窗口结果只有1个;如果窗口类型是一个翻转窗口或是一个跳跃大小hopSize > 窗口大小windowSize则不需要此操作。)
var percentOfSuccessfulEvents = from all in countAllEvents.ToPointEventStream() from successfull in countSuccessfulEvents.ToPointEventStream() select new { PercentOfSuccess = (double)successfull.Count / (double)all.Count * 100.0 };
结果如下:
方法二:
- 将匹配条件是否为"SUCCESS"转变为数值量
- 统计数值量的和以作为成功事件的总数
第1步,对数据源进行标记:
var annotatedSource = from ev in source select new { ev.SourceId, ev.Value, success = (ev.Status == "SUCCESS") ? 1 : 0 };
第2步,统计成功事件以及所有事件的总数:
var ratios = from win in annotatedSource.HoppingWindow( TimeSpan.FromMinutes(2), TimeSpan.FromMinutes(1), HoppingWindowOutputPolicy.ClipToWindowEnd) select new { countSuccessful = win.Sum(e => e.success), countAll = win.Count() };
第3步,计算成功事件占事件总数的比率:、
var percentOfSuccessfulEvents2 = from e in ratios select new { PercentOfSuccess = (double)e.countAll / (double)e.countSuccessful * 100.0 };
结果如下:
方法2相比方法1有两点好处:
- 不需要执行联接操作
- 不需要转换为点类型事件流
下一篇将介绍StreamInsight查询模式中的左外联接部分。