我想要三个值,它们是aggValueInLastHour
aggValueInLastDay
aggValueInLastThreeDay
。
我尝试过如下。
但我不想等待,意味着我不喜欢使用滑动窗口进行聚合。(3天窗口必须等待三天的数据,这对我们的系统来说是无法忍受的。)
如何在第一个事件发生时获得最近3天的聚合值?
提前感谢您的任何建议!
答案 0 :(得分:0)
如果您希望获得更频繁的更新,可以使用QueryableState
,以适合您用例的速率轮询状态。
答案 1 :(得分:0)
您可以使用ContinuousEventTimeTrigger,这会导致窗口在比完整窗口更短的时间内触发,从而可以看到中间状态。如果接收器的下游使用者期望每个输出都是部分聚合(而不是完整的当前状态)并将它们相加,则可以选择将其包装在PurgingTrigger中。
答案 2 :(得分:0)
我尝试了CEP。
代码:
AfterMatchSkipStrategy strategy = AfterMatchSkipStrategy.skipShortOnes();
Pattern<RiskEvent, ?> loginPattern = Pattern.<RiskEvent>begin("start", strategy)
.where(eventTypeCondition)
.timesOrMore(1)
.greedy()
.within(Time.hours(1));
KeyedStream<RiskEvent, String> keyedStream = dataStream.keyBy(new KeySelector<RiskEvent, String>() {
@Override
public String getKey(RiskEvent riskEvent) throws Exception {
// key by user for aggregation
return riskEvent.getEventType() + riskEvent.getDeviceFp();
}
});
PatternStream<RiskEvent> eventPatternStream = CEP.pattern(keyedStream, loginPattern);
eventPatternStream.select(new PatternSelectFunction<RiskEvent, RiskResult>() {
@Override
public RiskResult select(Map<String, List<RiskEvent>> map) throws Exception {
List<RiskEvent> list = map.get("start");
ArrayList<Long> times = new ArrayList<>();
for (RiskEvent riskEvent : list) {
times.add(riskEvent.getEventTime());
}
Long min = Collections.min(times);
Long max = Collections.max(times);
Set<String> accountList = list.stream().map(RiskEvent::getUserName).collect(Collectors.toSet());
logger.info("时间范围:" + new Date(min) + " --- " + new Date(max) + " 事件:" + list.get(0).getEventType() + ", 设备指纹:" + list.get(0).getDeviceFp() + ", 关联账户:" + accountList.toString());
return null;
}
});
也许您注意到,跳过策略skipShortOnes
是一种自定义策略。
在CEP lib中显示我的修改。
在枚举中添加策略。
public enum SkipStrategy { NO_SKIP, SKIP_PAST_LAST_EVENT, SKIP_TO_FIRST, SKIP_TO_LAST, SKIP_SHORT_ONES }
在AfterMatchSkipStrategy.java
public static AfterMatchSkipStrategy skipShortOnes(){ 返回新的AfterMatchSkipStrategy(SkipStrategy.SKIP_SHORT_ONES); }
在discardComputationStatesAccordingToStrategy
的{{1}}方法中添加策略操作。
案例SKIP_SHORT_ONES: int i = 0; 列表&gt;&GT; tempResult = new ArrayList&lt;&gt;(matchedResult); for(Map&gt; resultMap:tempResult){ if(i ++ == 0){ 继续; } matchedResult.remove(结果映射); } 打破;