Слюни: запуск правила, если набор событий имеет n различных значений для свойства

Предположим, у нас есть тип Event, который имеет 3 свойства: constraint, common и distinct. Цель состоит в том, чтобы написать правило в Drools, которое срабатывает, когда существует подмножество Events, удовлетворяющее следующим критериям:

  • Events произошло за последние t секунд; а также
  • Events Иметь ранее известное значение свойства constraint; а также
  • Поделиться ранее неизвестным значением свойства common; а также
  • Существует как минимум n различных значений для свойства distinct.

Если правило сработает, нам потребуется набор участвующих событий для дальнейшей обработки.

Как вы посоветуете нам подойти к этой проблеме?

Примечание 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

person fzwd    schedule 15.08.2017    source источник
comment
Первая ошибка, снижающая производительность, заключается в том, что вы цепляетесь за $event: Event, не убедившись, что оно не старше t секунд. Это приводит к тому, что правило запускается для старых событий, для которых может быть или не быть решения, и оно будет выполняться повторно в тех случаях, когда решение есть.   -  person laune    schedule 15.08.2017
comment
Другая ошибка заключается в том, что вы не останавливаетесь после сбора ArrayList, если он короче n. Только если его размер превышает n, возможно иметь по крайней мере одно подмножество из n различных различных значений.   -  person laune    schedule 15.08.2017
comment
Исходный код содержит эти ограничения, но прирост производительности, связанный с ними, почти незаметен. Я полагаю, что это будет выполняться повторно в случаях, когда есть решение, а повторяющиеся декартовы произведения, которые движок пытается вычислить, создают проблему с производительностью.   -  person fzwd    schedule 16.08.2017


Ответы (1)


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.

Возможно, вы захотите добавить правило для удаления пустых коллекторов.

person laune    schedule 15.08.2017
comment
Спасибо! Это решение кажется очень многообещающим и, по-видимому, решает проблему производительности. - person fzwd; 16.08.2017
comment
Поскольку вы нашли бумагу: там есть очень похожий образец, IIRC что-то прозванное глазком. - person laune; 16.08.2017