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

Drools - How to accumulate facts that don't share a property with a fact in working memory

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

假设我有一个 Person class,它有一个 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" 子句中一次遍历最终集合的内容;否则我会将源模式和 "not" 从 "from accumulate" 中移出并完全取消 "from accumulate"。

有什么方法可以实现我所描述的吗?提前致谢。

由于 $person.address 中的 "on-the-fly" 事实无法与 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 组件也是正确的事实,则所有这些都不是必需的。根据数据库设计中范式的数据模型也更适合 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) )

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

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

希望对您有所帮助,