Drools - 如何累积不与工作记忆中的事实共享属性的事实

时间:2016-02-05 03:03:49

标签: drools accumulate

我想从嵌套集合中创建一个事实集合,其中事实不与工作内存中的另一个事实共享属性。

假设我有一个Person类,它有一组Address对象。我希望来自Person John的所有地址事实的集合具有与当前工作记忆中的地址事实相同的邮政编码。

我认为这样做的唯一方法是使用“from accumulate”,但我无法弄清楚如何在源模式行中添加其他条件。当我尝试以下操作时,我收到规则编译错误:

when
    p:   Person(name == "John")
    h:   HashSet(size > 0) from accumulate (addr: Address(zc: zipcode) from p.addresses /*and not Address(zipcode == zc)*/, 
                                            init(Set s = new HashSet();)
                                            action(s.add(addr);),
                                            result(s) 
                                           )    

我需要一次性最终集合的内容来迭代“then”子句;否则我会移动源模式和“不”检查出“从累积”,并完全取消“从累积”。

有没有办法做我正在描述的事情?提前谢谢。

2 个答案:

答案 0 :(得分:0)

由于来自$person.address的“即时”事实无法与WM网络中的正确事实相结合,因此您将不得不依赖Java。

when
$person: Person(name == "John")
$except: HashSet from collect Address()
hashset: HashSet(size > 0)
            from accumulate (addr: Address() from $person.addresses, 
               init(Set s = new HashSet();)
               action( if( ! $except.contains(addr) ){
                         s.add(addr);
                       } ),
               result(s) )

如果Person的Address组件也是正确的事实,则所有这些都不是必需的。根据DB设计中的Normal Forms的数据模型也更适合Drools。

修改如果您只需要跳过包含特定邮政编码的地址,请累加一组邮政编码。

when
$person: Person(name == "John")
accumulate( Address($zip: zipcode); $except: collectSet($zip) )
hashset: HashSet(size > 0)
            from accumulate ($addr: Address( $zx: zipcode) from $person.addresses, 
               init(Set s = new HashSet();)
               action( if( ! $except.contains( $zx ) ){
                         s.add( $addr );
                       } ),
               result(s) )

答案 1 :(得分:0)

如果您要比较的地址已经是会话中的事实(并且您在会话中有其中一个或者您有办法唯一地识别它),那么您可以尝试这样的事情:

rule "Test"
    $p: Person(name == "John")
    $a: Address()
    $s: Set( size > 0 ) from collect (
        Address(zipcode != $a.zipcode) from $p.getAdresses()
    )
then
    //The Set $s contains all the addresses from John having
    //a different zipcode than the Address in your working memory. 
end

希望它有所帮助,