Drools:如果一组事件具有 属性 的 n 个不同值,则触发规则

Drools: Firing a rule if a set of events has n distinct values for a property

假设我们有一个具有 3 个属性的 Event 类型:constraintcommondistinct。目标是在 Drools 中编写一条规则,当满足以下条件的 Events 的子集存在时触发:

如果规则触发,我们需要一组参与事件进行进一步处理。

你建议我们如何解决这个问题?

注1:这个问题有点类似于link,史蒂夫的回答似乎很有希望但不完整。

注2:性能至关重要。我们已经成功开发了执行此任务的规则,但它们会显着降低整个规则库的性能,因此是不可接受的。

编辑 1:当前(性能不佳的)解决方案如下所示:

rule ""
when
    $event : Event(constraint == CONSTANT_VALUE)
    $events : ArrayList() from collect(
            Event(constraint == CONSTANT_VALUE, 
            common == $event.common)
            over window:time( t ))
    $distinctVals : Set( size >= n ) from accumulate(Event($d : distinct) from $events, collectSet($d))
then
    // process $events
end

Drools 不适用于需要对潜在的大量事实进行重复评估的计算。在这种情况下,您必须将详细信息卸载到某些 Java 代码中。

class Collector {
    String constraint;
    String common;
    List<Event> events = ...; // or Queue
    Map<String,List<Event>> dist2events = ...;
    int diversity;

    public void addEvent( Event e ){
        // 1. remove Event sets X from events older than t
        // 2. remove all members of X from dist2events,
        //    delete map elements where the value list is empty
        events.add( e );
        List<Event> ofDistinct = dist2events.get( e.getDistinct() );
        if( ofDistinct == null ){
            ofDistinct = new ArrayList<Event>(); 
            dist2events.put( ofDistinct );
        }
        ofDistinct.add( e );
        diversity = dist2events.keySet().size();
    }
}


rule createCollector
when
    Event( $constraint: constraint, $common: common )
    not Collector( constraint == constraint, common == $common )
then
    insert( new Collector( $constraint, $common ) );
end

rule addEvent
when
    $event: Event( $constraint: constraint, $common: common )
    $collector: Collector( constraint == constraint,
                           common == $common,
                           events not contains $event )
then
    modify( $collector ){ addEvent( $event ) }
end

rule MoreThan
when
    Collector( $constraint: constraint, $common: common,
               $events: events,
               diversity >= n )  // maybe only when n-1 to n?
then
    ... process $events
end

您必须决定是否希望此规则仅在超过阈值 n 时触发,或者当多样性 >= n 时集合发生变化时触发。

您可能想要添加一个规则来删除空的收集器。