5

ルール エンジンの使用についてもっと学びたいので、小さな Drools プロジェクトに取り組んでいます。Event次のフィールドを持つクラスがあります。

  • String tag;任意の文字列を指定できるタグ。
  • long millis;タイムスタンプ。(実際には、これは にもある JodaTimeLocalDateフィールドから変換されEventます。)
  • int value;理由が欲しい値。

ナレッジ ベースに数百のEventインスタンスを挿入し、 でタグ付けされた最新の 3 つのイベントを取得したいと考えています"OK"。私は次のコードを思いつきました。

rule "Three most recent events tagged with 'OK'"
when
    $e1 : Event( tag == "OK",
                 $millis1 : millis )
    $e2 : Event( tag == "OK",
                 millis < $millis1, $millis2 : millis )
    $e3 : Event( tag == "OK",
                 millis < $millis2, $millis3 : millis )

    not Event( tag == "OK",
               millis > $millis1 )
    not Event( tag == "OK",
               millis > $millis2 && millis < $millis1 )
    not Event( tag == "OK",
               millis > $millis3 && millis < $millis2 )
then
  # Do something with $e1.value, $e2.value and $e3.value
end

しかし、これを行うためのより良い方法があるはずだと感じています。value > 10これは非常に冗長で、簡単には再利用できません。たとえば、最新の 5 つのイベントを で取得したい場合はどうでしょうか。私は多くのコードをコピーして貼り付けることになりますが、それはしたくありません:)。また、コードは私にはあまり「美しく」見えません。not Event...制約の繰り返しはあまり好きではありません。また、同じタグ条件を何度も繰り返さなければならないのも好きではありません。(この例は、私の実際のアプリを大幅に単純化したもので、実際の条件はもっと複雑です。)

このコードを改善するにはどうすればよいですか?

4

2 に答える 2

4

STREAMイベント処理モードを使用していて、イベントがストリームで順序付けられていると仮定します。

rule "3 most recent events"
when
    accumulate( $e : Event( tag == "OK" ) over window:length(3),
                $events : collectList( $e ) )
then
    // $events is a list that contains your 3 most recent 
    // events by insertion order
end

=====編集====

以下のコメントに基づいて、Drools5.4以降で必要なことを実現する方法は次のとおりです。

declare window LastEvents
    Event() over window:length(3)
end

rule "OK events among the last 3 events"
when
    accumulate( $e : Event( tag == "OK" ) from window LastEvents,
                $events : collectList( $e ) )
then
    // $events is a list that contains the OK events among the last 3 
    // events by insertion order
end

私がこれを心から行っているので、構文を再確認するだけですが、これに近いはずです。

于 2012-08-24T15:06:33.390 に答える