您的$productsToChecks 声明中有语法错误:
$productsToChecks : Product(customerId != "21") && type not in ("A", "B") from $products
您要检查的两个属性都需要在 Product( ... ) 部分中,如下所示:
$productsToChecks: Product( customerId != "21",
type not in ("A", "B")) from $products
您在规则的其他部分也重复此错误。
所以你的要求是:
不要检查产品类型是“A”还是“B”以及客户 ID 为 21。对于任何其他产品,请检查 customerId 是否与 id 匹配,或者客户国家/地区是否设置为 null 并且国家/地区是否打开产品设置为“美国”
我们可以把它提炼成下面的伪代码:
- 何时
- 产品不是:(type=A 或 type=B)且 customerId=21
- (产品 customerId == 客户 ID)或(客户国家/地区 == null 和产品国家/地区 == 美国)
- 那就做点什么
鉴于第二部分中的“或”,这是两条规则。
我们需要做的第一部分是找到我们关心的产品子集。您可以通过多种方式做到这一点——collect 或 accumulate 是立即浮现在脑海中的两个。假设您问题中的要求是完整的,collect 在这里更合适(也更简单)。
Proposal($products: products, $customers: customers)
$productSubset: List() from collect( Product( customerId != 21, type not in ("A", "B") ) from $products)
现在您可以使用该产品子集(不包括您需要忽略的产品)来匹配您的其他条件。正如我所提到的,由于这些标准是 OR'd,它们应该是两个不同的规则。
rule "Product customerId matches Customer id"
when
Proposal($products: products, $customers: customers)
$productSubset: List()
from collect( Product( customerId != 21, type not in ("A", "B") ) from $products)
Customer( $id: id != null ) from $customers
$product: Product( customerId == $id ) from $productSubset
then
// do something with $product
end
rule "US Product and no Customer Country"
when
Proposal($products: products, $customers: customers)
$productSubset: List()
from collect( Product( customerId != 21, type not in ("A", "B") ) from $products)
Customer( country == null ) from $customers
$product: Product( country == "US" ) from $productSubset
then
// do something with $product
end
要减少重复代码,您可以将常用条件提取到单个“父”规则中,然后使用 extends 关键字创建两个具有不同条件的子规则。
我以这种方式设计这些规则是在假设您希望对符合您的标准的每个产品执行一些操作的情况下设计的。基于此假设,右侧将针对每个符合每个规则的条件的产品触发(另请注意,由于这两个规则不是互斥的,如果 customerId 匹配 和满足国家/地区要求。)
但是,如果您想要的结果只是满足条件的所有产品的列表,您可以再次使用函数来获取该产品列表。在这种情况下,accumulate 函数比collect 更合适:
rule "Get list of products for customer"
when
Proposal($products: products, $customers: customers)
$productSubset: List()
from collect( Product( customerId != 21, type not in ("A", "B") ) from $products)
Customer( $id: id != null, $country: country ) from $customers
$product: Product( customerId == $id ) from $productSubset
$customerProducts: List() from accumulate(
$p: Product((customerId == $id) || ($country == null && country == "US")) from $products,
collectList($p)
)
then
// do something with $customerProducts
end