2017-08-15 17 views
0

,commonおよびdistinctの3つのプロパティを持つEventタイプがあるとします。目標は、火災Event秒のサブセットは、それが次の基準を満たして存在していることをDroolsのルールで記述することです:Drools:イベントのセットがプロパティに対してn個の異なる値を持つ場合のルールの実行

  • Event sが最後トン秒で起こったが、および
  • Event s constraintプロパティの値はとなりました。以前はでした。そして
  • 以前に共有する不明の値はcommonです。そして、ルールが発火した場合
  • distinctプロパティ

ための少なくともn個異なる値がありますが、私たちはさらなる処理のため、参加イベントのセットを必要としています。

この問題にどのようにアプローチすることをお勧めしますか?

注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 
+0

パフォーマンスを損なう最初の失敗は、これがt秒を超えていないことを確認せずに '$ event:Event'にラッチすることです。これにより、ソリューションが存在する場合とそうでない場合がある古いイベントに対してルールが実行され、ソリューションがある場合は繰り返し実行されます。 – laune

+0

もう1つの間違いは、これがnよりも短い場合にArrayListを収集した後に停止しないことです。そのサイズがnを超える場合に限り、異なるn個の異なる値の少なくとも1つのサブセットを有することが可能である。 – laune

+0

元のコードにはこれらの制約が含まれていますが、これらの制約から生じるパフォーマンスの向上はほとんど無視できます。私はこれを信じます - >「それは解決策がある場合には繰り返し実行されます」とエンジンが計算しようと試みた繰り返しのデカルト積は性能問題を作り出します。 – fzwd

答えて

0

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は設定の変更を超えたりするたびにされている場合にのみ発動するかどうかを決定する必要があります。

空のコレクターを削除するルールを追加できます。

+0

ありがとうございます!このソリューションは非常に有望であり、パフォーマンスの問題を一見解決します。 – fzwd

+0

私はあなたの白書[Production Systems in Design Systems](https://engage.redhat.com/forms/rule-design-patterns)につまづいていました。非常に洞察力のある。私はすべてのDroolsの新人にそれをお勧めします。乾杯! – fzwd

+0

あなたはこの論文を見つけたので、そこにIIRCの "peephole"という愛称があります。 – laune

関連する問題