0

私はよだれを垂らすのはまったく初めてです。

drools エンジンが毎秒一連のイベントを取得するアプリケーションに取り組んでいます。過去 10 秒間のすべてのイベントの属性値が 10 未満かどうかを確認する必要があります。条件が true の場合は、何らかの処理を行う必要があります。これが私が試したサンプルコードです。問題を理解して解決するのを手伝ってください。

私のルールファイル.....

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;


declare Employee 
@role (event)
@expires(10s)
end

// Using timer to ensure rule processing starts only after 10 secs, 
//else processing starts as soon as first event comes in
rule "Test Timer"
no-loop true
10timer(int: 5s)
when
$E : Employee()
$total : Number( doubleValue < 1 ) 
    from accumulate( Employee( Age > 10 ), count() )
then 
   System.out.println(  $E.getName() + " is crossing the threshold of 20");
retract($E);
end

そしてメインクラス

// import classes removed from here...
public class MainClass {

/**
 * @param args
 */
public static void main(String[] args){

    //Create KnowledgeBase...
    KnowledgeBase knowledgeBase = createKnowledgeBase();

    //Create a stateful session
    StatefulKnowledgeSession session = knowledgeBase.newStatefulKnowledgeSession();
//  KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newConsoleLogger(session);
    try {

        // Using random generator to simulate the data.
        int randomInt=0;
        Random randomGenerator = new Random();
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date date = null; 

        while (true) {
            Thread.sleep(1000);
            date = new Date();
            randomInt = randomGenerator.nextInt(12);

            //Create Facts and insert them      
            Employee emp = new Employee();
            emp.setName("Anurag" + randomInt);
            emp.setAge(randomInt);

            //LOAD THE FACT AND FIREEEEEEEEEEEEEEEEEEE............
            System.out.println(dateFormat.format(date)+ " => Random no " + randomInt);
            session.insert(emp);
            session.fireAllRules();
        } 

    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        session.dispose();
    }
}

    /**
    * Create new knowledge base
    */
private static KnowledgeBase createKnowledgeBase() {
    KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
            //Add drl file into builder
    File drl = new File("D:\\eclipse\\worspace\\Research\\misc\\testforall.drl");
    builder.add(ResourceFactory.newFileResource(drl), ResourceType.DRL);
    if (builder.hasErrors()) {
        System.out.println(builder.getErrors().toString());
        //throw new RuntimeException(builder.getErrors().toString());
    }

    KnowledgeBase knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
            //Add to Knowledge Base packages from the builder which are actually the rules from the drl file.
    knowledgeBase.addKnowledgePackages(builder.getKnowledgePackages());
    KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();

    config.setOption( EventProcessingOption.STREAM );
    return knowledgeBase;
}
}

public class Employee {
private String Name;
private int Age;
// getter - setters
}
4

2 に答える 2

2

Drools Fusionのドキュメントを確認しましたか?まず第一に、従業員はイベントの良いアイデアとは思えません。イベントは、ドメインに関連する何かの状態の意味のある変化です。したがって、イベントは、従業員がオフィスに到着した時間、または出発した時間である可能性がありますが、従業員自体は、イベントというよりもドメインエンティティ(またはルールエンジンのファクト)です。Droolsフュージョン時間演算子の使用に興味がある場合は、最後の10秒間に何が起こっているかを常に確認できるスライディングウィンドウ(時間ウィンドウ)について読むことをお勧めします。そのためにタイマーを使用する必要はありません。乾杯

于 2012-04-09T16:58:15.813 に答える
1

実行した場合、実行したときに何が起こったかを忘れていました。

エンティティ セットがそれほど大きくない場合、この問題はベースの Drools ディストリビューションで非常に簡単に解決できると思います。

私はあなたのものに似たアプリを持っていて、私のために働いています:

rule "Clear only auxiliar fact"
  salience 1
  when
    af: AuxFact()
  then
    DroolsRepository.retractFact(af);
end

rule "Clear auxiliar fact and an old meaningful fact"
  salience 1000
  when 
    af: AuxFact()
    mf: MeaningfulFact()
  then
    if(DroolsRepository.getCurrentTimeMillis() - tmf.getCreationDate().getTime() > 5000){
      DroolsRepository.retractFact(af);
      DroolsRepository.retractFact(mf);
      // YOUR MEANINGFUL CODE
    }
    else{
      DroolsRepository.retractFact(af);}
end

query "getAllFacts"
  $result: Fact()
end

// Boot rules re-executing thread.
new Thread(new Runnable(){
  public void run(){
  do{
    kSession.insert(new AuxFact());
    try{
      Thread.sleep(99);}
    catch(InterruptedException e){
      e.printStackTrace();}}
  while(true);}
}).start();

同様のアプローチは、よりシンプルで効果的です。

于 2013-06-27T17:48:06.037 に答える