Drools规则在一段时间内未触发

huangapple go评论158阅读模式
英文:

Drools Absence of hitting a rule over a perios of time

问题

以下是翻译好的内容:

我对Drools还不熟悉。我需要使用spring-boot和Drools(7.40.0.Final)构建一个应用程序,其中springboot应用程序会从外部源流式传输数据包(与实体移动相关的跟踪数据)到我的应用程序。我需要评估所有这些流式数据。

我正在使用一个名为“geofence_rule.drl”的文件来存储与地理位置相关的规则。

规则“房间1中标签位置的规则”
当
    model:ComponentModel(positionValue <= 50)
然后
    model.setRoomId(1);
end

规则“房间2中标签位置的规则”
当
    model:ComponentModel(positionValue > 50)
然后
    model.setRoomId(2);
end

模型类如下。

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ComponentModel{
	
    private long tagId;
    private long roomId;
    private int positionValue;

}

我可能会获得与“n”个标签(例如tag1,tag2,tag3等)相关的位置数据。我需要计算在过去的5分钟内tag1是否不在房间1中(这意味着tag-1的数据没有命中“房间1中标签位置的规则”)。Drools中是否支持这种计算?

我在Drools文档中看到了“not”关键字。但它只是否定规则的条件。我需要检查规则在过去几分钟内是否命中,这个时间限制在应用程序中是可配置的。

英文:

I am new to Drools. I need to build an application with spring-boot & Drools(7.40.0.Final) where springboot application streams an external source that will continuously trigger data packets (tracking data related to movement of an entity) to my application. I need to use evaluate all these streaming data.

I am using a "geofence_rule.drl" file to keep the rules related to the geographic locations.

rule &quot;Rule for Tag position in room 1&quot;
when
    model : ComponentModel(positionValue &lt;= 50)
then
    model.setRoomId(1);
end

rule &quot;Rule for Tag position in room 2&quot;
when
    model : ComponentModel(positionValue &gt; 50)))
then
    model.setRoomId(2);
end

Model class is as below.

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ComponentModel{

    private long tagId;
    private long roomId;
    private int positionValue;

}

I may get position related data of "n" number of tags say tag1, tag2 tag3 and so on. I need to calculate if tag1 is absent from Room-1 (which means tag-1's data does not hit "Rule for Tag position in room 1") for Last 5 minutes. Is there any support in Drools for such calculation?

I have seen "not" keyword in drools documentation. But it just negating the condition of Rule. I need to check rule hiting nature for last few minutes, this time limit is configurable in application.

答案1

得分: 1

你正在寻找流模式负模式。这些链接指向官方的Drools文档。

流模式是Drools中的两种事件模式之一。默认模式是“云”模式,在这种模式下,你提前拥有所有事实并且它会自动进行决策。另一种模式是“流”模式,用于处理时间流,听起来很像你的“ping”应用程序。在流模式中,Drools会在每个事实进入时对其进行评估,并且意识到时间——即其他事实何时存在。

流模式中的负模式是not关键字的逻辑时间扩展。正如你正确指出的,在云模式中,它仅否定条件(例如“在工作内存中没有与此条件匹配的条件。”)。然而,在流模式中,你可以更新这些模式以在一段时间内生效。

Drools文档提供了以下示例:

rule "Sound the alarm"
when
  $h: Heartbeat() from entry-point "MonitoringStream"
  not(Heartbeat(this != $h, this after[0s,10s] $h) from entry-point "MonitoringStream")
then
  // Sound the alarm.
end

‘when’子句中的第一行标识了心跳的实例($h)。第二行标识了在10秒内未收到心跳的情况。如果这两个条件都为真,则执行规则——在这种情况下会触发警报。

你可以将相同的模式应用于你的规则。

rule "Tag has not been in Room 1 for 5 minutes"
when
  // Tag with ID 1, present in Room 1 -- First instance
  $tag: ComponentModel( tagId == 1, roomId == 1 ) from entry-point "TrackingStream"

  // Trigger if this condition hasn't been met a second time within 5 minutes
  not( ComponentModel( 
    this != $tag, 
    tagId == 1,
    roomId == 1,
    this after[0s, 5m] $tag ) from entry-point "TrackingStream")
then
  // Do whatever it is you need to do for this condition
end

在这种情况下,我在 after 时间操作符中利用了这一点(链接到Drools文档)。

基本上,它的工作原理如下:

$tag: ComponentModel( tagId == 1, roomId == 1 ) from entry-point "TrackingStream"

第一个条件标识了这种情况,即在这种情况下,ID 1在房间1中存在。它标识了我们正在跟踪的该情况的当前实例。由于这是一个时间流,可以简单地将其视为“标记实体(1)刚刚进入房间1”。

not( ComponentModel( 
  this != $tag, 
  tagId == 1,
  roomId == 1,
  this after[0s, 5m] $tag 
) from entry-point "TrackingStream")

这是魔法发生的地方,语法需要一些时间来适应。第二个条件在下一个时间点等待并检查条件。检查的条件有:

  • TagID为1,
  • RoomId为1

时间约束(this after[0s, 5m] $tag)表示等待以检查此条件。如果在$tag之后的这个时间范围内收到第二个ComponentModel,则规则不会触发,并且该情况将重复等待多达另外5分钟。由于时间范围[0s, 5m]立即开始检查,我们需要在not(...)子句中明确地排除$tagthis != $tag)。


为了说明,这是它可能执行的方式(简化):

  • 0分:00秒 - 事件A 〜 接收(id = 1,房间 = 1)。$tag = 事件A。我们开始检查第二个条件的传入流。
  • 0分:30秒 - 事件B 〜 接收(id = 2,房间 = 1)。ID不匹配;被忽略。
  • 0分:45秒 - 事件C 〜 接收(id = 1,房间 = 1)。事件A规则匹配'取消'。现在正在检查$tag = 事件C。
  • 5分:45秒 - 在5分钟窗口内未收到匹配事件,触发事件C规则右侧。
英文:

You're looking for stream mode and negative patterns. The links are to the official Drools documentation.

Stream mode is one of two event modes in Drools. The default is "cloud" mode, where you have all of the facts up front and it makes decisions automatically. The other mode, "stream" mode, is intended for processing temporal streams, which sounds a lot like your "pinging" application. In stream mode, Drools evaluates each fact as it comes in, and is aware of time -- namely when other facts were in.

Negative patterns in stream mode are the logical temporal extension of the not keyword. As you correctly pointed out, in cloud mode it simply negates a condition (eg. "there is no condition in working memory that matches this criteria.") In stream mode, however, you can update these patterns to take effect over a period of time.

The Drools documentation provides this example:

rule &quot;Sound the alarm&quot;
when
  $h: Heartbeat() from entry-point &quot;MonitoringStream&quot;
  not(Heartbeat(this != $h, this after[0s,10s] $h) from entry-point &quot;MonitoringStream&quot;)
then
  // Sound the alarm.
end

The first line in the 'when' clause identifies an instance of a heartbeat ($h). The second identifies the situation when a heartbeat is not received within 10 seconds. If both conditions are true, the rule is executed -- in this case an alarm is triggered.

This is the same pattern you'd apply for your rule.

rule &quot;Tag has not been in Room 1 for 5 minutes&quot;
when
  // Tag with ID 1, present in Room 1 -- First instance
  $tag: ComponentModel( tagId == 1, roomId == 1 ) from entry-point &quot;TrackingStream&quot;

  // Trigger if this condition hasn&#39;t been met a second time within 5 minutes
  not( ComponentModel( 
    this != $tag, 
    tagId == 1,
    roomId == 1,
    this after[0s, 5m] $tag ) from entry-point &quot;TrackingStream&quot;)
then
  // Do whatever it is you need to do for this condition
end

In this case, I'm leveraging the after temporal operator (link to Drools documentation.)

Basically this is how it works--

$tag: ComponentModel( tagId == 1, roomId == 1 ) from entry-point &quot;TrackingStream&quot;

The first condition identifies the scenario, in this case ID 1 is present in Room 1. It identifies the current instance of that situation we're tracking. Since this is a temporal stream, it's easy to think of it as "Tagged entity (1) has just entered Room 1."

not( ComponentModel( 
  this != $tag, 
  tagId == 1,
  roomId == 1,
  this after[0s, 5m] $tag 
) from entry-point &quot;TrackingStream&quot;)

This is where the magic happens, and the syntax takes a bit getting used to. This second condition is waiting for the next temporal and then checking the conditions. The conditions checked are:

  • TagID is 1,
  • RoomId is 5

The temporal constraint (this after[0s, 5m] $tag) says to wait to check this condition. If a second ComponentModel is received within this time-frame after $tag, then the rule will not trip, and the scenario will repeat waiting for up to another 5 minutes. Since the time range [0s, 5m] starts checking immediately, we need to exclude $tag explicitly from the matching in the not(...) clause (this != $tag.)


To illustrate, this is how it might execute (simplified):

  • 0m:00s - Event A ~ received (id = 1, room = 1). $tag = Event A. We begin checking incoming streams for the second condition.
  • 0m:30s - Event B ~ received (id = 2, room = 1). ID mismatch; ignored.
  • 0m:45s - Event C ~ received (id = 1, room = 1). Event A rule match 'cancelled'. Now checking for $tag = Event C.
  • 5m:45s - No matching events received in 5 minute window, rule for Event C triggers right hand side.

huangapple
  • 本文由 发表于 2020年8月20日 13:40:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/63498921.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定