2012-08-23 36 views
4

我正在研究一个小Drools项目,因为我想了解更多关于使用规则引擎的信息。我有一个名为Event类具有以下字段:Drools:获取3个最新事件

  • String tag;它可以是任何字符串的标签。
  • long millis;时间戳。 (实际上,这是从JodaTime LocalDate字段,也是在Event转换。)
  • int value;值,我想要的原因。

我插入几百Event情况下进入我的知识基础,现在我想标记有"OK" 3个最近的事件。我想出了下面的代码,它的作品:

rule "Three most recent events tagged with 'OK'" 
when 
    $e1 : Event(tag == "OK", 
       $millis1 : millis) 
    $e2 : Event(tag == "OK", 
       millis < $millis1, $millis2 : millis) 
    $e3 : Event(tag == "OK", 
       millis < $millis2, $millis3 : millis) 

    not Event(tag == "OK", 
       millis > $millis1) 
    not Event(tag == "OK", 
       millis > $millis2 && millis < $millis1) 
    not Event(tag == "OK", 
       millis > $millis3 && millis < $millis2) 
then 
    # Do something with $e1.value, $e2.value and $e3.value 
end 

但我有一种感觉应该有更好的方式来做到这一点。这非常详细,不容易重复使用:例如,如果我想要获得最近发生的五个事件(例如value > 10),该怎么办?我最终会复制粘贴很多代码,而我不想这样做:)。 此外,代码对我来说看起来并不“美丽”。我不太喜欢重复的约束条件,而且我也不喜欢一遍又一遍地重复相同的标签条件。 (这个例子是我真实应用程序的一个非常简化的版本,其中的条件实际上更加复杂。)

我该如何改进这段代码?

回答

4

假设你使用的是流事件的处理方式和您的活动流中下令:

rule "3 most recent events" 
when 
    accumulate($e : Event(tag == "OK") over window:length(3), 
       $events : collectList($e)) 
then 
    // $events is a list that contains your 3 most recent 
    // events by insertion order 
end 

=====编辑====

基于您的评论波纹管,在这里是如何实现你的Drools 5.4+想要的东西:

declare window LastEvents 
    Event() over window:length(3) 
end 

rule "OK events among the last 3 events" 
when 
    accumulate($e : Event(tag == "OK") from window LastEvents, 
       $events : collectList($e)) 
then 
    // $events is a list that contains the OK events among the last 3 
    // events by insertion order 
end 

只需仔细检查语法,因为我的心脏这样做,但它应该是接近这一点。

+0

谢谢!那看起来很有希望但是,我无法让它工作。它什么也不做,drl文件中的其他规则也停止触发。我已经设置了'EventProcessingOption.STREAM',并在drl文件中用'@role(event)'声明了我的Event类。我可能错过了别的东西;你有什么主意吗? – jqno

+0

假设您正在使用Drools 5.4,您可能还需要使用@expires(x)为您的事件定义到期时间,其中x是您希望将事件保留在内存中的时间。 –

+0

我发现哪里出了问题:从最近的3个事件中,它带有标记为“OK”的那些事件,但我需要的是标记为“OK”的3个最近事件,而不管其他标记为可能与它们交错。所以我没有收到任何活动,因为在过去3年中没有发生任何“OK”事件。所以,这仍然不能解决我的问题,但不幸的是......但它很接近:)。 – jqno