流口水时间约束和“现在” [英] drools time based constraints and "now"

查看:132
本文介绍了流口水时间约束和“现在”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在尝试写一个流口水,说如果事件发生在上周,执行后果。我们有常规的java日期对象代表事件发生的时间,但是我们不确定如何在LHS中表达我们希望该日期对象在上周发生的流口水。重要的是,一周的时间是任意的。随时可能更改为月或年。最后,请记住,我们的会话是有状态的。

We are trying to write a drool which says something like "If the event happened in the last week, execute the consequence". We have regular java date objects representing the time the event happened, but we aren't sure how to express in the LHS of a drool that we want that date object to have taken place in the last week. Importantly, the timespan of a week is arbitrary. It could change to month or year at any time. Finally, keep in mind that our session is stateful.

我在这里找到一个有点相关的问题:
在规则的LHS中使用java.util.Date 。我将从下面的答案中引用最相关的摘录:

I found a somewhat related question here: use java.util.Date in a rule's LHS . I will quote the most relevant excerpt from the answer below:


如果您在无状态会话中执行,那么您的方法
将与Fusion运营商结合使用。然而,它仍然不是一个
的推荐做法。一个更好的方法是定义一个事实,
调用它现在,它包含一个单一的Date字段。初始化并插入
以及其他事实,然后对其进行理由,而不是
全局。

If you are executing within a stateless session, then your approach will work in combination with the Fusion operators. It is still not a recommended practice, however. A better approach is to define a fact, call it Now, which contains a single Date field. Initialize and insert it along with your other facts then reason against it instead of a global.

如果你有一个有状态的会话,它会变得更棘手,因为
的实时时间在会话空闲时传出,这意味着你现在的
越来越过时了。我们解决这个
的方法是通过使用WorkingMemoryEventListener。我们使用
监听器的
objectInserted,objectRetracted和objectUpdated方法来保持我们的Now事实当前(我们不关心精度
不到一分钟,所以我们检查一分钟是否已经通过从
最后更新,以避免不必要的开销)。如果
工作内存没有改变,规则将不会被评估,所以使用这个监听器就足够了
确保当需要更新Now时(除非你有
查询依赖于现在的价值是现在,但另一个
主题)。

If you have a stateful session, it gets more tricky because real time is passing even while the session is idle, meaning your Now fact is getting more and more out of date. The way we have solved this is via the use of a WorkingMemoryEventListener. We use the objectInserted, objectRetracted, and objectUpdated methods of this listener to keep our Now fact current (we do not care about precision less than one minute so we check whether a minute has passed from the last update to avoid unnecessary overhead). Rules won't evaluate if working memory isn't changing, so using this listener is sufficient to ensure that Now is updated when it needs to be (unless you have queries that depend on the current value of Now, but that's another topic).

在答案中,作者描述了表示的问题的现在。他的解决方案似乎是黑客,答案是在较早版本的流口水中发布的。我正在提出一个新的问题,以更好地关注这个问题,而不是在我链接的一个通过的治疗。

In the answer, the author describes problems with the representation of "now". His solution seems hacky and the answer was posted in a much earlier version of drools. I'm making a new question here to give better attention to this question specifically rather than the passing treatment it gets in the one I linked.

更新: / strong>

UPDATE:

时间戳是简单的java.util.Date对象。

Timestamps are the simple java.util.Date object.

事件通过api调用添加到会话中。有状态会话是由基于java的api所持有的对象。 api在提交知识会话时增加事件。 FireAllRules每秒钟发生一次。

Events are added to the session via api call. The stateful session is an object held by a java based api. The api adds events to the knowledge session when they are submitted. FireAllRules occurs about once per second.

推荐答案

根本的问题(经常)是什么要求 em>意思。事件发生在上周可能是任何事情发生7 * 24 * 60 * 60秒前;这可能是从2015年12月星期一到现在,或从20151227星期日到现在,或者类似的事情,只是在日期重要,而不是一天的时间。

The fundamental question (as so often) is what the requirement really means. An event "happening in the last week" could be anything happening 7*24*60*60 seconds ago; it could be something that has happened from Monday 20151228 up to now, or from Sunday 20151227 until now, or maybe something similar where just the date matters and not the time of the day.

请问这是什么意思,并相应地重新表述你的问题。

Ask what it really means, and rephrase your question accordingly.

如果你需要一个滑动窗口,从现在回来,即这一刻在某个时间间隔( w 秒)之前,您仍然需要定义执行此检查的速度和准确性。 Drools在其绝对意义上没有不断更新的现在的概念。可以创建并维护一个代表现在的近似的事实,使用计时器(优于使用听众)。现在事实必须定期更新,每个 d 秒。如果您在 后面的时间戳中插入新事件,则最后更新为 d 秒。 (如果您在过去使用 w w + d 秒之间插入时间戳的新事件,则可能会触发规则。)

If you do need a sliding window, going back from "now", i.e., verily this moment, for a certain time interval (of w seconds), you still need to define the speed and accuracy with which this check has to be performed. Drools does not have a continually updated notion of "now" in its absolute sense. It is possible to create and maintain a fact representing an approximation of "now", using a timer (which is preferable to using a listener). The Now-fact has to be updated periodically, every d seconds. If you insert a new event with a time stamp after the last update of Now, it will not be recognized for up to d seconds. (And if you insert a new event with a time stamp between w and w + d seconds in the past, it is possible that it triggers the rule.)

由于您没有指出如何插入事件以及他们的时间戳如何实现,我无法提供说明我所概述的规则。请参阅Drools文档Timers and Calendars。

Since you haven't indicated how you insert events and how their time stamps are implemented I cannot provide rules illustrating what I have outlined. See the Drools documentation about "Timers and Calendars".

修改

在这个问题上还没有说过事件的时间关系(即,当它真的发生在现实世界中)和它的时间戳(即当它被输入时进入工作记忆)。在最后一周或每月或第二天的事件时间戳的规则检查是徒劳的:这一定是正确的。

What has not been said in the question is the relation of an event's time (i.e., when it really happened in the real world) and its timestamp (i.e., when it was entered into Working Memory). Rules checking for an events timestamp being in the last week or month or second are futile: this will be invariably true.

如果你叫fireAllRules一个简单的方法,在一个简单的方式之前,重复一次,在时间段内更新时间戳1周(月,...)。或在每次通话前立即更新。两者都远离hacky。​​

If you call fireAllRules repeatedly, updating the time horizon with a timestamp 1 week (month,...) back before the call is one simple way. Or update Now before each call. Both is far from "hacky".

这篇关于流口水时间约束和“现在”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆