drools:规则执行不止一次

Sam*_*rat 5 drools

我正在尝试Drools规则引擎,我是一个初学者.

我在单个规则文件中有以下规则:

rule "A stand alone rule" 
salience 2
no-loop
when
    $account : Account()
    Account($account.balance>100)
then
    System.out.println("balance>100");
    System.out.println($account.getBalance());
    System.out.println($account.getCustomer().getName());    
end

rule "A second Rule"
salience 1
no-loop
when
    $account : Account()
    Account($account.balance<100)
then
    System.out.println("balance<100");
    System.out.println($account.getBalance());
    System.out.println($account.getCustomer().getName());
end 
Run Code Online (Sandbox Code Playgroud)

在StatefulKnowledgeSession中,我通过了两个账户,一个账户余额为15000,另一个账户余额为15,

Account account=new Account(7l,15000l);
        Account account1=new Account(5l,15l);

        Customer customer = new Customer("Samrat", 28, "Sector51", account);
        Customer customer1 = new Customer("Alexi", 28, "Sector50", account1);
        account.setCustomer(customer);
        account1.setCustomer(customer1);
        session.insert(account);
        session.insert(account1);

        session.fireAllRules();
Run Code Online (Sandbox Code Playgroud)

根据我的预期结果应该是每个规则应该只被触发一次,并且应该打印相应的对象.

但我得到的结果是:

balance>100
15000
Samrat
balance>100
15000
Samrat
balance<100
15
Alexi
balance<100
15
Alexi
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么每条规则都运行两次????

Est*_*rti 6

使用多个模式(并且不指定它们之间的任何关系)将创建完整的笛卡尔积(就像在没有join子句的多个表上的select一样).所以,规则:

rule A
when
    Account()
    Account()
then
    ...
end
Run Code Online (Sandbox Code Playgroud)

对于类型为Account的N个对象,将激活N ^ 2次.一种解决方案可能是使用魔术字段'this'来指定第二个帐户与第一个帐户相同:

rule A
when
    $a: Account()
    Account(this == $a)
then
    ...
end
Run Code Online (Sandbox Code Playgroud)

但是,回到你的例子,我认为你甚至不需要使用2种不同的模式.您可以按如下方式重写规则:

rule "A stand alone rule" 
salience 2
no-loop
when
    $account: Account(balance>100)
then
    System.out.println("balance>100");
    System.out.println($account.getBalance());
    System.out.println($account.getCustomer().getName());    
end

rule "A second Rule"
salience 1
no-loop
when
    $account: Account(balance<100)
then
    System.out.println("balance<100");
    System.out.println($account.getBalance());
    System.out.println($account.getCustomer().getName());
end
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你,