在一段时间内不遵守规则

vhipe2zx  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(471)

我不太会流口水。我需要用springboot&drools(7.40.0.final)构建一个应用程序,在这个应用程序中,springboot应用程序流式传输一个外部源,它将不断地触发数据包(跟踪与实体移动相关的数据)到我的应用程序。我需要评估所有这些流数据。
我使用一个“geofinence\u rule.drl”文件来保存与地理位置相关的规则。

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

rule "Rule for Tag position in room 2"
when
    model : ComponentModel(positionValue > 50)))
then
    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”关键字。但它只是否定了规则的条件。我需要检查过去几分钟的规则命中性质,这个时间限制是可配置的应用程序。

mhd8tkvw

mhd8tkvw1#

你在寻找流模式和负面模式。这些链接指向官方的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"

第一个条件标识场景,在本例中,房间1中存在id 1。它确定了我们正在跟踪的当前情况。因为这是一个时态流,所以很容易将其视为“标记的实体(1)刚刚进入房间1”

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

这就是魔法发生的地方,语法需要一点时间来适应。第二个条件是等待下一个时态,然后检查条件。检查的条件是:
tagid为1,
室友5岁
时间约束( this after[0s, 5m] $tag )说等着检查这个情况。如果在此时间范围内收到第二个componentmodel $tag ,则规则将不会跳闸,并且场景将重复等待最多5分钟。从时间范围 [0s, 5m] 立即开始检查,我们需要排除 $tagnot(...) 条款( this != $tag .)
为了说明这一点,可以这样执行(简化):
0m:00s-收到事件a(id=1,房间=1)。 $tag =事件a。我们开始检查第二个条件的传入流。
0米:30秒-收到事件b(id=2,房间=1)。id不匹配;忽略。
0米:45秒-事件c~收到(id=1,房间=1)。事件a规则匹配“已取消”。正在检查 $tag =事件c。
5m:45s-在5分钟窗口内没有收到匹配的事件,事件c的规则触发右侧。

相关问题