我在尝试用Drools(6.4.Final)编写规则时遇到了一些困难。 要么我的规则不完全正确,要么我最终为同一目标编写了几条规则但没有信念。我希望根据您的经验和/或参考资料获得您的意见,以帮助我。
我有一个事实(类型C),其中包含一个E.
列表每个E:
每个R:
我想检查一年/每年是否某种类型的R的金额总和超过一个值。 如果它超过了,我想插入一个事实(X)与后面的所有E。
我的第一次尝试是:
# Realm Object Server Configuration
#
# For each possible setting, the commented out values are the default values
# unless another default is mentioned explicitly.
#
# Paths specified in this file can be either absolute or relative.
# Relative paths are relative to the current working directory.
auth:
## The path to the public and private keys (in PEM format) that will be used
## to validate identity tokens sent by clients.
## These configuration options are MANDATORY.
public_key_path: /etc/realm/token-signature.pub
private_key_path: /etc/realm/token-signature.key
providers:
## Providers of authentication tokens. Each provider has a configuration
## object associated with it. If a provider is included here and its
## configuration is valid, it will be enabled.
## Possible providers: cloudkit, debug, facebook, realm, password
## Providers 'realm' and 'password' are always enabled:
## - The 'realm' provider is used to derive access tokens from a refresh token.
## - The 'password' provider is required for the dashboard to work. It supports
## authentication through username/password and uses a PBKDF2 implementation.
## This enables authentication via a Google Sign-In access token for a
## specific app.
google:
## The client ID as retrieved when setting up the app in the Google
## Developer Console.
clientId: '<SOME-HASH-HERE>.apps.googleusercontent.com'
## This enables authentication via a Facebook access token for a specific app.
## This provider needs no configuration (uncommenting the next line enables it).
facebook: {}
它正在运作,但X中的元素存在问题,可能没有任何R或R与期望类型不匹配...
我的第二次尝试是:
几个但更简单的规则声明了一种类型,以帮助累积数据并使用单个E。
rule "Sum of R exceed for one year"
when
C( $listOfE : listOfE )
// Pick one E
E( $year : year ) from $listOfE
// All Es of the same year
// "collectLists" is a custom accumulate function that simply adds all the elements of a list
accumulate ( E(year == $year, $listofR : listofR ) from $listOfE;
$allR : collectLists($listofR))
// Check the sum
// "sumbd" is a custom accumulate function that simply adds BigDecimal (sum is broken for that in 6.4)
accumulate ( R( type == « X », $amount : amount ) from $allR;
$sum : sumbd($amount);
$cumulAnnee > 20000)
then
insert( new X($year, $elements));
end
但是我对这个解决方案并不自信,看起来(非常)很复杂。 最后,我希望有一个易于理解和维护的简单规则。
由于
答案 0 :(得分:1)
一种简单的方法是在一次通过中收集所有E和R的所有总和并返回Map<YearType,BigDecimal>
YearType
结合年份和类型,并且您可以提取Entry对象检查BigDecimal等等。
我不确定你是否可以编写一个返回Map的自定义累加函数,但是可以使用“传统”累积语法来完成,你可以使用init,action和result子句来编写你需要的任何东西。
这是您可能使用的累积版本的简短版本:
Map() from accumulate( E( $lr: listOfR != null, $y: year )
init( Map m = new HashMap(); )
action( for( int i = 0; i < $lr.size(); ++i ){
//... add to m.get($y) observing R's type
} )
result( m ) )