2012-08-23 68 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