论坛首页 Java企业应用论坛

技巧: Drools中from,accumulate和collect之间的关联

浏览 3144 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-07-17  
 

 'from', 'accumulate' 'collect' 之间的关联<o:p></o:p>

作者: Mark Proctor <o:p></o:p>

Drools4.0中,我们介绍了‘from’关键字,它允许你为模式声明一个推论的来源。这允许引擎使用不在Working Memory中的数据进行推论。源数据可能是绑定变量的子字段,或者方法调用的结果;后一种方式提供了与Hibernate集成的方法(通过调用命名的查询),Drools将把返回的结果与模式统一为一体。<o:p></o:p>

这里是一些简单的绑定子字段进行推论的例子:<o:p></o:p>

Person( personAddress : address )
address : Address( zc : zipcode == "23920W") from personAddress<o:p></o:p>


利用Drools引擎提供的新的表示方法带来的灵活性,你可以用很多办法来解决这个问题。下面是同样的结果,但是用“.”来实现。<o:p></o:p>


p : Person( )
address : Address( zc : zipcode == "23920W") from p.address<o:p></o:p>


当然,我们也可以使用新的表达式语言扩展来完成:<o:p></o:p>


Person( zc : address.zipCode == "2392OW")<o:p></o:p>


下一个例子举例如何在一个hibernate查询结果上进行推论,Restaurant模式将依次在每一个结果上进行推论和绑定。<o:p></o:p>


p : Person( )
  Restaurant( food == p.favouriteFood )
                from hs.getNamedQuery( "list restaurants by postcode" )
                     .setProperties( [ "postcode" : p.address.zipcode ] )
                     .list()<o:p></o:p>


'collect'
'accumulate' 在一个返回的对象上计算结果,这种模式可以指定‘from’作为它的源。'collect'允许对集合推论并且返回对象列表。'accumulate'允许对集合中每一个数据项执行操作,匹配给定模式并且执行操作返回用户选择的对象——通常用来求和或汇总数据,当然也可以用来做更复杂的工作。                                                                                                                                                                                                                                                                                                                                                                                                                                                               <o:p></o:p>

<o:p> </o:p>

示例将两个from连在一起使用。它绑定所有购买的每样东西(item)的价值都超过10元的Customer(客户),itemsCustomer的字段,没有设置在Working Memory中。

c : Customer()
items : List( size == c.items.size )
      from collect
( Item( price > 10 ) from c.items )<o:p></o:p>

这里的List是从collect产生的,其中有size的属性。<o:p></o:p>


如果这里的items不是Customer的字段,但被设置到working memory中,我们可以使用一个相互关联的‘collect’模式。<o:p></o:p>


  p : Customer ()
list : List()
      from collect( Item( owner : p ) ) //
找到拥有者是p的所有Item
items : List(size == list.size)
      from collect( Item( price > 10 ) from list )<o:p></o:p>


下面是如何使用'accumulate'达到同样的效果,它建立在'count'函数中;虽然这不与'from'举例关联,在这里将它做为一个补充。<o:p></o:p>


  p : Person()
count : Number()
      from accumulate( i : Item( owner == p ), count( i ) )
list : List( size == count )
      from collect( Item( owner == p, price > 10 ) )<o:p></o:p>


对于更复杂的情况——深奥但是更具说明性,我们可以看下面的‘from’例子。对每一个Store(商店),购物的Person(顾客)有一个account(账目),我们返回PersonStore中所有购买的商品,并检查是否这些商品的价值平均超过50元的客户Person<o:p></o:p>


p : Person()
s : Store( accountOwner == p )
a : Number( intValue > 50 )
  from accumulate( item : Item( )
                   from collect( Item( store == s )
                                 from hs.getNamedQuery( "get user items in store" )
                                        .setProperties( [ "store" : s.name, "owner" : p.name ] )
                                        .list() ),
                   average( item.price ) )<o:p></o:p>


因此对于那些Rete不能处理集合和嵌套或者working memory外的数据的说法,我希望这些可以让你改变想法。<o:p></o:p>



<o:p></o:p>

<o:p> </o:p>

论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics