Drools检查列表中的一个属性是否存在于其他列表中
我得到以下结构:Drools检查列表中的一个属性是否存在于其他列表中,drools,business-rules,kie,drools-flow,Drools,Business Rules,Kie,Drools Flow,我得到以下结构: public class Proposal { private final List<Product> products; private final List<Customer> customers; } public class Customer { private String id; private String country; } public class Product { private String c
public class Proposal {
private final List<Product> products;
private final List<Customer> customers;
}
public class Customer {
private String id;
private String country;
}
public class Product {
private String customerId;
private String country;
private String type;
}
感谢您的帮助或建议您的
$productsToChecks
声明中有语法错误:
$productsToChecks : Product(customerId != "21") && type not in ("A", "B") from $products
您要检查的两个属性都需要位于产品(…)
部件内部,如下所示:
$productsToChecks: Product( customerId != "21",
type not in ("A", "B")) from $products
在规则的其他部分也会重复此错误
因此,您的要求是: 对于id为21的客户,不要检查产品类型是否为“A”或“B”。对于任何其他产品,请检查customerId是否与id匹配,或者客户国家/地区是否设置为空,以及产品上的国家/地区是否设置为“美国” 我们可以将其提取为以下伪代码:
- 什么时候
- 产品不是:(类型=A或类型=B)且客户ID=21
- (产品customerId==客户id)或(客户国家==空且产品国家==美国)
- 那就做点什么
收集
或累积
是您立即想到的两种方法。假设问题中的要求是完整的,collect
在这里更合适(也更简单)
现在,您可以使用该产品子集(不包括您需要忽略的产品)来匹配其他标准。正如我提到的,由于这些标准是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匹配且满足国家/地区要求,则产品可能会触发两次。)
但是,如果结果是满足条件的所有产品的列表,则可以再次使用函数获取该产品列表。在这种情况下,累积
功能比收集
功能更合适:
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
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
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