Esper отличные события на нескольких атрибутах - PullRequest
0 голосов
/ 31 января 2019

У меня проблема с семантикой потока в Esper.Моя цель - выводить только события с попарно различными атрибутами.Кроме того, существуют временные условия, которые должны соблюдаться между атрибутами (см. Espers Ссылка на интервальную алгебру ).

Пример оператора:

insert into output_stream select a.*, b.*
from stream1#length(100) as a, stream2#length(100) as b
where a.before(b) or a.meets(b) or a.overlaps(b)

Попарно различные атрибуты означаютЯ хочу убедиться, что нет двух выходов o1, o2 , где o1.a = o2.a or o1.b = o2.b.Чтобы привести более конкретный пример, если есть результаты

o1: (a = a1, b = b1),
o2: (a = a1, b = b2),
o3: (a = a2, b = b2),
o4: (a = a2, b = b1)

, то должны быть выведены только два из них (например, o1 и o3 или o2 и o4).Какой из них на данный момент не имеет значения.

Я хотел бы выполнить попарно различные атрибуты с помощью предложения NOT EXISTS, например:

NOT EXISTS ( 
    select * from output_stream#length(100) as otherOutput 
    where a = otherOutput.a or b = otherOutput.b )

, которое работает частично, для последовательного вывода утверждение o1.a = o2.a or o1.b = o2.b всегда выполняется.

Однако, когда stream1 сначала доставляет несколько «a», а затем stream2 доставляет одну «b», что соответствует условиям, которые должны быть объединены с обеими «a», тамНесколько выходов одновременно .Это не охватывается моим предложением NOT EXISTS, поскольку на одном и том же шаге происходит несколько выходов с одинаковыми буквами "b", и, следовательно, они еще не включены в ключевое слово output_stream.

. distinctздесь не подходит, так как он проверяет все атрибуты вместе, а не попарно.Аналогично, простой group by для всех атрибутов не подходит.Мне бы хотелось иметь в качестве критерия что-то вроде «отличное от а и отличное от б», но оно не существует.

Я мог бы решить эту проблему с помощью вложенных group by с, где я группирую по каждому атрибуту

select first(*) from (select first(*) from output_stream group by a) group by b

, но, согласно одному из комментариев, не имеет четко определенной семантики в системах потоковой обработки.Таким образом, Esper не разрешает подзапросы в части запроса from.

Мне нужен способ принудительно выводить только один вывод за раз и, таким образом, условие NOT EXISTS перепроверяться при каждом последующемвыводить данные или каким-либо образом проверять выходные данные, которые происходят одновременно, перед фактической вставкой их в поток.

Обновление: синхронизация вывода не очень критична.output_stream будет использоваться другими такими утверждениями, поэтому я могу учесть задержки, увеличив длину окон.stream1 и stream2 доставляют события в порядке их startTimestamp свойства.

1 Ответ

0 голосов
/ 01 февраля 2019
create schema Pair(a string, b string);
create window PairWindow#length(100) as Pair;
insert into PairWindow select * from Pair;
on PairWindow as arriving select * from PairWindow as other  
  where arriving.a = other.a or arriving.b = other.b

Вот пример самосоединения с использованием именованного окна, в котором хранятся последние 100 пар.

РЕДАКТИРОВАТЬ: Приведенный выше запрос был разработан для моего понимания исходных требований.Ниже запрос рассчитан на новые уточнения.Он проверяет, было ли у «a» или «b» какое-либо предыдущее значение (в последних 100 событиях оставьте #length (100) по мере необходимости)

create schema Pair(a string, b string);
create window PairUniqueByA#firstunique(a)#length(100) as Pair;
create window PairUniqueByB#firstunique(b)#length(100) as Pair;

insert into PairUniqueByA select * from Pair;
insert into PairUniqueByB select * from Pair;

select * from Pair as pair
  where not exists (select a from PairUniqueByA as uba where uba.a = pair.a)
  and not exists (select a from PairUniqueByB as ubb where ubb.b = pair.b);
...