我正在尝试对元素数组运行条件,其中每个元素包含多个参数。 我想评估一个动态条件(如用户的输入),我想检查是否:
(($person1: PersonClass(getName() == "tom") from $persons) || ($person2: PersonClass(getAddress() == "x") from $persons) && ($person3: PersonClass(getCarType() == "aa" from $persons)) && PersonClass($person1 == $person2, $person2 = $person3) from $persons)
我收到错误:
unable to resolve method using strict-mode: PersonClass.$person1()]
[Near : {... $person1 == $person2 ....}]
问题是Drools评估第一组(名字等于tom,地址等于x的
||
,如果为真,则继续下一部分。而如果第一组为真,则这个被选中的人不需要拥有一辆“aa”类型的汽车(可以是 $persons 列表中的任何其他人,即使其名字不是 Tom 或者其地址不是“x”)
如何强制 Drools 检查同一个人对象上整个条件的属性?
我正在使用最新版本的 Drools (9.44.0.Final)
如何强制 Drools 检查同一个人对象上整个条件的属性?
您同时对同一个对象运行所有检查。
你的例子有点复杂,所以我将使用一个更简单的例子。假设我们有一个 Fruit 对象数组,每个对象都有一些属性——名称、颜色、价格。
// Fruits in working memory:
{ name: "strawberry", color: "red", price: 0.75 },
{ name: "tomato", color: "red", price: 2.50 },
{ name: "apple", color: "green", price: 1.00 },
{ name: "blueberry", color: "blue", price: 0.50 }
考虑这个when子句:
when
Fruit( color == "red", price < 1.00 )
此条件将匹配红色且价格低于 1.00 美元的水果。考虑到上面列出的工作内存中的对象,它只会匹配草莓(第一项)。不会与番茄匹配,因为不满足价格条件;而且不会和蓝莓相配,因为价格合适,但颜色不好。
比较一下:
when
Fruit( color == "blue" )
Fruit( price > 2.00 )
此规则将与蓝莓的第一个检查(颜色==蓝色)相匹配。然后,它将第二张支票与唯一价格超过 2.00 美元的水果(番茄)进行匹配。西红柿不是蓝色的,但这两个条件没有应用于同一个水果,因为它们处于不相交的检查中。
回到你的规则,一个好的经验法则是,如果你发现自己写的是“或”条件,那么你很可能应该有两条规则。
首先,Drools 错误根本与
||
无关。事实上,从语法上来说,这个条件根本没有意义:
PersonClass($person1 == $person2, $person2 = $person3) from $persons
不幸的是,我什至无法开始尝试弄清楚你想在这里做什么。
作为一个完全疯狂的猜测,如果您想查看是否有一个名为 Tom 且地址为 X 的人,或者一个地址为 X 且地址为 AA 的人,那么您应该编写如下两条规则:
rule "Tom at address x"
when
$person: PersonClass(name == "tom", address == "x") from $persons
then
// ...
end
rule "address X with car type AA"
when
$person: PersonClass(address == "x", carType == "aa") from $persons
then
// ...
end