首页 > 解决方案 > drools中重复的pojo验证规则

问题描述

我在 kiesession 中插入了大约 1000 个 A 类型的 pojo,如果 kiesession 中 A 存在重复的 pojo,我如何在 drools 中添加规则来完成某些任务。

class A {
     private int someInt;
     private String someString;
}

function boolean checkDuplicate(List input) {
    int a = input.size();
    int b = ((List) input.stream().distinct().collect(Collectors.toList())).size();
    return a!=b;
}

dialect "java"
rule "ADuplicateRule"
   when
        $input : List( ) from collect(A())
        eval(checkDuplicate($input))
   then
        throw new Exception("A list has duplicate values");
end

上述方法有效,但有没有更好更简单的方法来实现这一点?

喜欢在 kiesession 中对 pojo 字段的总和进行验证,我们可以简单地写这个

$sumSomeInt: Integer(this > 90) from accumulate(A( $SomeInt: someInt ), sum($SomeInt))

是否可以在类似的行上做一些事情来检查重复项?

标签: droolsrule-engine

解决方案


你非常接近:

rule "Duplicates Found"
when
  A( $i: someInt, $s: someString )
  List( size > 1 ) from collect( A( someInt == $i, someString == $s ) )
then 
  // handle the duplicate case
end

根据需要调整您的相等检查。我建议不要从“then”中抛出异常。

或者,您甚至不需要收集完整的重复列表;至少存在一个副本就足够了。这使您的规则更像这样:

rule "Duplicates found - v2"
when
  $a: A( $i: someInt, $s: someString )
  exists( A( this != $a, someInt == $i, someString == $s ))
then
  // handle the duplicates case
end

在这些规则中,我们利用了 Drools 会隐式检查A工作记忆中的所有实例的事实。因此,在第一条规则中,对于 each A,它将检查该实例是否存在重复;如果有,规则触发。否则,它会检查 的下一个实例A,依此类推,直到 的所有实例A都被求值。

第二条规则依赖于相同类型的工作流,但还包括this != $aexists子句的检查,以验证我们发现的“重复”实际上不是我们正在检查的实例。由于第一条规则仅触发List( size > 1 ),因此它希望我们检查的实例将包含在collect.


推荐阅读