簡體   English   中英

流口水基於時間的限制和“現在”

[英]drools time based constraints and “now”

我們正在嘗試寫流口水,上面寫着“如果事件在上周發生,請執行結果”。 我們有常規的Java日期對象來表示事件發生的時間,但是我們不確定如何在流口水的LHS中表示我們希望該日期對象在上周發生。 重要的是,一周的時間是任意的。 它可以隨時更改為月或年。 最后,請記住我們的會議是有狀態的。

我在這里找到了一個相關的問題: 在規則的LHS中使用java.util.Date 我將從以下答案中引用最相關的摘錄:

如果您在無狀態會話中執行,那么您的方法將與Fusion運算符結合使用。 但是,仍然不建議這樣做。 更好的方法是定義一個事實,將其稱為Now(立即),其中包含一個Date(日期)字段。 初始化並與其他事實一起插入它,然后針對它而不是全局原因進行推理。

如果您有狀態的會話,那么它將變得更加棘手,因為即使會話處於空閑狀態,實時時間也會過去,這意味着您的Now事實越來越過時了。 我們解決此問題的方法是使用WorkingMemoryEventListener。 我們使用此偵聽器的objectInserted,objectRetracted和objectUpdated方法來使我們的Now事實保持最新(我們不在乎不到一分鍾的精度,因此我們檢查從上一次更新起是否經過一分鍾以避免不必要的開銷)。 規則不會評估工作內存是否沒有更改,因此使用此偵聽器足以確保在需要時立即更新Now(除非您的查詢依賴於Now的當前值,但這是另一個主題)。

在回答中,作者描述了“現在”表示的問題。 他的解決方案似乎很笨拙,答案發布在更早的版本中。 我在這里提出一個新問題,以便更具體地關注此問題,而不是在我所鏈接的問題中獲得通過的待遇。

更新:

時間戳是簡單的java.util.Date對象。

通過api調用將事件添加到會話中。 有狀態會話是由基於Java的api持有的對象。 api在事件提交后將其添加到知識會話。 FireAllRules大約每秒發生一次。

基本問題(通常如此)是需求的真正含義。 事件“發生在上周”可能是7 * 24 * 60 * 60秒前發生的任何事情; 可能是從20151228星期一到現在,或者從20151227星期日到現在發生了,或者可能只是日期很重要,而不是一天中的時間。

詢問其真正含義,然后相應地改寫您的問題。

如果確實需要一個滑動窗口,請從“現在”返回,即恰好是這一刻,在一定的時間間隔( w秒)內,您仍需要定義執行此檢查的速度和准確性。 從絕對意義上講,Drools並沒有不斷更新“現在”的概念。 使用計時器(可能比使用偵聽器更好)可以創建和維護一個表示“現在”的近似值的事實。 事實必須每d秒定期更新一次。 如果您在最后一次更新即時之后插入帶有時間戳的新事件,則最多d秒將無法識別該事件。 (並且,如果您插入一個新事件,該事件的時間戳在過去的ww + d秒之間,則有可能觸發該規則。)

由於您尚未指出如何插入事件以及如何實現事件的時間戳,因此我無法提供規則說明我所概述的內容。 請參閱有關“計時器和日歷”的Drools文檔。

編輯

問題中沒有說的是事件的時間 (即事件在現實世界中真正發生的時間 )與其時間戳 (即事件被輸入到工作記憶中)之間的關系。 檢查事件時間戳記在最后一周,一個月或第二秒的規則是徒勞的:這將始終是正確的。

如果您反復調用fireAllRules,則在調用之前回溯1周(月,...)的時間戳來更新時間范圍是一種簡單的方法。 或在每次通話前立即更新。 兩者都不是“ hacky”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM