Агрегаты
В примерах из этого раздела показано выполнение агрегатных операций с окнами событий. Поддерживаются следующие агрегатные функции.
Среднее значение для числового поля полезных данных (avg).
Суммирование по полю полезных данных (sum).
Минимальное значение для поля полезных данных (min).
Максимальное значение для поля полезных данных (max).
Количество событий (count).
Агрегаты — это операции на основе множеств. Они выполняют вычисления с подмножествами данных. Такие подмножества задаются в виде окон событий, которые группируют события по временной шкале. Согласно этому определению, агрегаты могут применяться только к окнам и не могут применяться к обычным потокам событий. Они предоставляются в виде методов расширения в CepWindowStream<T>. Дополнительные сведения об окнах см. в разделе Использование окон событий.
В агрегатных операциях используется тот же синтаксис, что в операциях проекций, и их результатами являются скалярные поля полезных данных. Агрегаты для окон вычисляются поэтапно, то есть в случае, когда событие попадает в окно агрегата или покидает его, результаты предыдущего вычисления агрегата обновляются. Учтите, что это может повлиять на точность чисел.
avg, sum, min и max принимают один входной параметр, представляющий значение для статистической обработки. Обычно этим параметром является ссылка на поле события. Входной параметр задается в виде лямбда-выражения, как показано в следующих примерах. Агрегат count подсчитывает все события в окне и не принимает параметра.
Обработка значений NULL выполняется в соответствии с аналогичными функциями в Transact-SQL.
В функции sum значение NULL считается равным 0 (нулю).
В функции min любое значение считается меньше, чем NULL.
В функции max любое значение считается больше, чем NULL.
В функции TopK, если события ранжируются по полю полезных данных, то значение NULL считается меньше любого другого значения.
Функции минимума и максимума можно использовать с любым типом, реализующим интерфейс сравнения, например с числовым, лексикографическим (string) или временным (datetime).
Примеры
В приведенных ниже примерах показано применение агрегатных функций к событиям, определенным в разделах Прыгающие окна и Окна моментальных снимков. Обратите внимание, что в данном выпуске окна Окна количества нельзя использовать со встроенными агрегатами и TopK.
А. Вычисление агрегата для «прыгающего» окна
«Прыгающее» окно повторяется на временной шкале с постоянным периодом. Например, статистическая обработка данных событий за час с повторным вычислением каждые пять минут соответствует «прыгающему» окну размером 1 час и длиной прыжка 5 минут, как показано в следующем примере.
// Assuming the following input event type for inputStream:
public class MyPayload
{
public int i;
public float f;
}
var avgHourly = from win in inputStream.HoppingWindow(TimeSpan.FromHours(1), TimeSpan.FromMinutes(5))
select new { hourlyavg = win.Avg(e => e.f) };
Ко входному потоку применяется оконный оператор, создающий поток CepWindowStream<T>. Каждый элемент win в этом потоке представляет окно, содержащее события.
В следующем примере подсчитываются события за каждый полный час. Для этого используется «переворачивающееся» окно, то есть «прыгающее» окно, у которого длина прыжка равна размеру окна.
var countHourly = from win in hourStream.TumblingWindow(TimeSpan.FromHours(1))
select new { count = win.Count() };
Б. Вычисление агрегата для окна моментального снимка
В следующем примере предложение from применяет окно моментального снимка к потоку inputStream. В данном примере результаты агрегата Sum присваиваются полю полезных данных e.i, а результаты агрегата Avg вычисляются по полю полезных данных e.f. Кроме того, используется агрегат count. В примере также показано, как объединить несколько агрегатов в одной инструкции. Все агрегаты вычисляются в пределах одного окна.
// Assuming the following input event type for inputStream:
public class MyPayload
{
public int i;
public float f;
}
// Multiple aggregations over a snapshot window
var snapshotAgg = from w in inputStream.Snapshot()
select new { sum = w.Sum(e => e.i),
avg = w.Avg(e => e.f),
count = w.Count() };
Предусмотрена возможность внедрять статистические выражения в сложные выражения, причем любое выражение может содержать больше чем одно статистическое выражение, как показано в следующем примере.
var result = from w in inputStream.Snapshot()
select new { ratio = w.Sum(e => e.i) / w.Sum(e => e.f) };