【原创】StreamInsight查询系列(十八)——查询模式之趋势发现

上篇文章介绍了查询模式中如何应对瞬变及报警泛滥,这篇博文将介绍StreamInsight中的趋势发现。

测试数据准备

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

var sourceData = new []
{
    new { SourceId = "A", Value = 22, Status = 1, TimeStamp = DateTime.Parse("10/23/2009 4:12:00 PM") },
    new { SourceId = "A", Value = 24, Status = 0, TimeStamp = DateTime.Parse("10/23/2009 4:13:00 PM") },
    new { SourceId = "A", Value = 31, Status = 1, TimeStamp = DateTime.Parse("10/23/2009 4:14:00 PM") },
    new { SourceId = "A", Value = 67, Status = 0, TimeStamp = DateTime.Parse("10/23/2009 4:15:00 PM") },
    new { SourceId = "A", Value = 54, Status = 0, TimeStamp = DateTime.Parse("10/23/2009 4:16:00 PM") },
    new { SourceId = "A", Value = 50, Status = 1, TimeStamp = DateTime.Parse("10/23/2009 4:30:00 PM") },
    new { SourceId = "A", Value = 87, Status = 0, TimeStamp = DateTime.Parse("10/23/2009 4:35:00 PM") },
};

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

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

趋势发现

问题:怎样将点类型事件流转变为间隔类型事件流,且保证每一个间隔包含了当前点事件和前一个点事件?

实现将点类型事件流转变为连续间隔类型事件流(或叫做“信号流”),通常可以通过剪辑事件达到效果。与剪辑事件息息相关的函数则是ClipEventDuration,它采用两个流作为参数,并且根据第二个流中下一匹配事件的开始时间更改第一个流中每个事件的生存期。

解决该问题,我们可以采取3步走:

  1. 扩展每一个点事件,并剪辑到下一个对应事件;
  2. 将每一个间隔事件向后移动一个刻度,以保证它可以和下一个事件重叠;
  3. 与原始事件流联接,将两个点事件的负载放在一起

下面是具体的实现:

var result = from s in source
            .AlterEventDuration(s => TimeSpan.MaxValue)
            .ClipEventDuration(source, (s, e) => s.SourceId == e.SourceId)
            .ShiftEventTime(e => e.StartTime + TimeSpan.FromTicks(1))
             join e in source on s.SourceId equals e.SourceId
             select new
             {
                 StartValue = s.Value,
                 EndValue = e.Value,
                 Delta = e.Value - s.Value,
                 Duration = e.TimeStamp - s.TimeStamp
             };

结果如下:

下一篇将介绍StreamInsight查询模式中如何检测异常。

posted @ 2011-09-09 00:17  StreamInsight  阅读(1287)  评论(1编辑  收藏  举报