【问题标题】:Esper Aggregation ResultsEsper 聚合结果
【发布时间】:2018-06-18 17:34:41
【问题描述】:

假设我有一个事件。该事件有 5 列。类型栏、姓名栏、来电号码、检测时间戳栏和收费栏。 Esper 产生以下 9 个元组:

[Event, CallPOPDWH, 385984MBSNE, time_1, 10]  
[Event, CallPOPDWH, 385984MBSNE, time_2, 30]
[Event, CallPOPDWH, 3859157UQHNI,time_3, 40]
[Event, CallPOPDWH, 3859157UQHNI,time_4, 40]
[Event, CallPOPDWH, 385984MBSNE, time_5, 40]
[Event, CallPOPDWH, 3859157UQHNI,time_6, 45]
[Event, CallPOPDWH, 385984MBSNE, time_7, 30]
[Event, CallPOPDWH, 385984MBSNE, time_8, 90]
[Event, CallPOPDWH, 385984MBSNE, time_9, 70]

我想编写一个查询,它将作为结果返回,对于每个呼叫号码,所有检测时间戳,只要费用总和大于 100。只要它找到例如呼叫号码的元组:

385984MBSNE,3859157UQHNI with sum(charge)>100 

它会返回:

[385984MBSNE,[time_1, time_2, time_5,time_7],120]
[3859157UQHNI,[time_3, time_4, time_6],125]
[385984MBSNE,[time_8, time_9],160]

重要的是存储每个呼叫号码的时间戳的窗口,当费用总和大于 100 时关闭。然后它将再次打开,直到找到与 sum>100 条件匹配的元组。I尝试过类似的东西:

select calling_number,
       window(timestamp).distinctOf(),
       sum(charge)
from Event.std:groupwin(calling_number).win:expr_batch(sum(total_call_charge_amount) > 100)
group by calling_number

select calling_number,
       window(timestamp).distinctOf(),
       sum(charge)
from Event.std:groupwin(calling_number).win:time(120 second))
group by calling_number
having sum(e.total_call_charge_amount) > 100 

它们似乎都不能正常工作。我观察到时间戳窗口不会删除以前的时间戳。任何帮助都会非常感激。

【问题讨论】:

    标签: sql sum aggregation complex-event-processing esper


    【解决方案1】:
    select calling_number,
           window(timestamp).distinctOf(),
           sum(charge)
    from Event.win:time(120 second))
    group by calling_number
    having sum(total_call_charge_amount) > 100 
    

    group-by 子句不正确。否则你所拥有的非常接近。

    Windows 不会关闭。我认为您想说的是,您只想每 120 秒输出第一行(首先使用输出),或者您想丢弃呼叫号码的所有累积数据并重新开始(参见上下文或命名窗口为此)或其他什么?

    对于给定的呼叫号码发生输出后从零开始,这是一种使用命名窗口的解决方案。

    create window EventWindow#time(120) as Event;
    
    insert into EventWindow select * from Event;
    
    insert into ThresholdDetected select calling_number,  window(timestamp).distinctOf(), sum(charge)
    from EventWindow
    group by calling_number
    having sum(total_call_charge_amount) > 100;
    
    on ThresholdDetected as td delete from EventWindow as ew where ew.calling_number = td.calling_number;
    

    【讨论】:

    • 你是完全正确的。我写错了,我更正了。我想要的是,如果 esper 为每个 call_number 找到一些元组,其总和大于 100,那么它应该输出这些元组的时间戳。然后,如果它继续接收这样的元组并且只要满足求和条件,它就应该为相同的调用编号继续相同的过程。同时,如果它已经输出它,它应该忘记该调用的先前时间戳。你说得对,我应该在 esper 的手册中看到上下文章节,但是一些帮助会很好。
    • 加上忘记时间戳,总和会改变吗?那么当有“385984MBSNE”的输出时,总和是为零还是总和保持在 120 还是总和是最后到达事件的值 30?
    • 根据我对 385984MBSNE 的示例:10+30+40+30=110。现在 sum>100 所以我们得到带有 4 个时间戳的输出。然后总和变为零。在一个事件之后:总和 = 90.然后 mext 事件来了:90+70=160 所以 sum>100 并且我们再次得到带有 2 个时间戳的输出。只要有更多 385984MBSNE 的元组来,相同的过程就会继续。
    • 我要处理的唯一问题是,一旦总和大于 100,esper 不会删除特定呼叫号码的先前结果。在我的示例中,它的输出:[385984MBSNE,[time_1,time_2 , time_5,time_7],120] [385984MBSNE,[time_1, time_2, time_5,time_7,time_8, time_9],280] 而不是上面提到的我想要的。
    • 好吧,如果我理解正确的话,您想从零和没有记录的情况下重新开始。命名窗口可能是最简单的。我会更新答案。
    猜你喜欢
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多