上篇博文介绍了StreamInsight基础查询操作中的分组排序部分。这篇文章将主要介绍如何StreamInsight查询中的决胜排序(Ranking and Tiebreaking)。

测试数据准备

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

var sourceData = new[]
{
    new { Name = "A", Count = 2, TieBreaker = 1 },
    new { Name = "A", Count = 3, TieBreaker = 2 },
    new { Name = "A", Count = 1, TieBreaker = 3 },
    new { Name = "A", Count = 2, TieBreaker = 4 },
    new { Name = "B", Count = 3, TieBreaker = 1 },
    new { Name = "B", Count = 3, TieBreaker = 2 },
    new { Name = "B", Count = 1, TieBreaker = 3 },
    new { Name = "C", Count = 2, TieBreaker = 1 },
    new { Name = "D", Count = 1, TieBreaker = 1 }
};

接下去将sourceData转变为点类型复杂事件流:

var inputStream = sourceData.ToPointStream(Application,
    t => PointEvent.CreateInsert(new DateTime(2011, 8, 24, 23, 0, 0, DateTimeKind.Utc), t),
    AdvanceTimeSettings.IncreasingStartTime);

决胜排序

问题1:怎样找出名字(Name)相同的事件中数量(Count)值最大的2个事件,若结果中存在多个数量值相同的情况,再根据TieBreaker优先选择较小者。

和上一部分介绍的分组排序类似,我们需要在分组排序的基础上更改orderby的条件来解决该问题:

var top2WithoutTieQuery = from e in inputStream
                          group e by e.Name into g
                          from e in (from win in g.SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
                                     from e in win
                                     orderby e.Count descending, e.TieBreaker
                                     select e).Take(2)
                          select e;

将top2WithoutTieQuery 内容导出如下:

 

问题2:怎样找出名字(Name)相同的事件中数量(Count)为所有事件中最大值的2个事件,若结果事件数不足2个,则输出仅有的1个。

问题2稍微复杂一些,我们首先得要找出所有数量为最大数量的事件,然而这些事件中找出TieBreaker最小的两个事件组。

var top2WithTie = from e in inputStream
                  group e by e.Name into g
                  from e in
                      (from win in
                           (from win in g.SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
                            from e in win
                            orderby e.Count descending
                            select e).Take(1).SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
                       from e in win
                       orderby e.TieBreaker
                       select e).Take(2)
                  select e;

在上面的代码中,

from win in g.SnapshotWindow(SnapshotWindowOutputPolicy.Clip)
from e in win
orderby e.Count descending
select e).Take(1)

取出了每一个事件组中Count等于最大数量的所有事件,虽然是Take(1),但是显示结果表明同一事件组内不止一个事件被取出,如Name为'B’的事件组中取出了两个事件(Name = B,Count = 3,TieBreaker = 1以及Name = B,Count = 3,TieBreaker = 2)。

 from e in win
 orderby e.TieBreaker
 select e).Take(2)
则是在最大数量相同事件中取出最多不超过2个的TieBreaker最小的事件。

最终的结果如下:

下一篇将介绍StreamInsight基础查询操作中的最后一篇——联接部分。

作者: StreamInsight 发表于 2011-08-25 09:29 原文链接

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"