Drools Don';忽略一个特征会使基于地图的事实变得松散
当我们试图将一个特征“don”到基于地图的模型时,我们遇到了流口水的问题 似乎在不使用特征后,基于地图的事实会消失(或收回)。 使用trait属性访问模型属性似乎没有任何问题 在以下场景中,预期为:Drools Don';忽略一个特征会使基于地图的事实变得松散,drools,Drools,当我们试图将一个特征“don”到基于地图的模型时,我们遇到了流口水的问题 似乎在不使用特征后,基于地图的事实会消失(或收回)。 使用trait属性访问模型属性似乎没有任何问题 在以下场景中,预期为: 将向引擎提供一个填充的基于地图的事实 我们根据规则中的约束修改基于地图的事实 我们根据映射事实检查约束,并应用特征 我们在后续规则中使用特征和模型 在规则5中,无论我是否向trait添加“bmi”属性并尝试设置该属性和/或将该属性放入基于地图的事实中,它仍然没有达到此规则(或规则3之后的任何内容)
public class TraitDonningTest extends CommonTestMethodBase
{
@Test
public void should_see_map_after_don() throws IOException
{
final String rule = Files.asCharSource(new File("src/test/resources/rules/traits.drl"), Charset.defaultCharset())
.read();
KieSession ks = loadKnowledgeBaseFromString(rule).newKieSession();
TraitFactory.setMode(VirtualPropertyMode.MAP, ks.getKieBase());
MyModel model = new MyModel();
model.put("weight", 1.0);
ks.insert(model);
ks.fireAllRules();
//We should have an updated BMI here
assertEquals(3.0, model.get("bmi"));
}
/**
* The real model based off of a map
*/
public static class MyModel extends HashMap<String, Object>
{
}
}
package drools
import TraitDonningTest.MyModel
declare MyModel
@Traitable
end
declare trait MyTrait
@PropertyReactive
height : Double
weight : Double
end
rule "1 - Update Model"
when
$model: MyModel(
this['weight'] != null,
this['height'] == null )
then
modify($model) {
put('height', 2.0)};
System.out.println("Rule 1");
end
rule "2 - Apply Trait"
dialect "mvel"
no-loop
when
$model: MyModel(
this['weight'] != null,
this['height'] != null)
then
System.out.println("Rule 2A: " + $model.get('weight') + " (before don)");
MyTrait trait = don($model, MyTrait.class);
System.out.println("Rule 2B: " + $model.get('weight') + " (after don)");
System.out.println("Rule 2C: " + trait.weight );
end
rule "3 - Check Trait"
dialect "mvel"
when
$trait : MyTrait()
then
System.out.println("Rule 3: " + $trait.weight);
end
rule "4 - Check Model"
dialect "mvel"
when
MyTrait()
$model: MyModel()
then
System.out.println("Rule 4A: " + $model.get('height'));
System.out.println("Rule 4B: " + $model.get('weight'));
end
rule "5 - Compute Map"
when
$model : MyModel()
MyTrait(
$height : height,
$weight : weight)
then
double compute = $height + $weight;
modify($model) {
put('bmi', compute)};
System.out.println("Rule 5: " + $model.get('bmi'));
end
rule "6 - Summarize Results"
when
$a: Number() from accumulate( MyModel(), count(1) )
$b: Number() from accumulate( MyTrait(), count(1) )
then
System.out.println("Model: " + $a);
System.out.println("Trait: " + $b);
end
Rule 1
Rule 2A: 1.0 (before don)
Rule 2B: 1.0 (after don)
Rule 2C: 1.0
Rule 3: 1.0
Model: 0
Trait: 1
输出:
public class TraitDonningTest extends CommonTestMethodBase
{
@Test
public void should_see_map_after_don() throws IOException
{
final String rule = Files.asCharSource(new File("src/test/resources/rules/traits.drl"), Charset.defaultCharset())
.read();
KieSession ks = loadKnowledgeBaseFromString(rule).newKieSession();
TraitFactory.setMode(VirtualPropertyMode.MAP, ks.getKieBase());
MyModel model = new MyModel();
model.put("weight", 1.0);
ks.insert(model);
ks.fireAllRules();
//We should have an updated BMI here
assertEquals(3.0, model.get("bmi"));
}
/**
* The real model based off of a map
*/
public static class MyModel extends HashMap<String, Object>
{
}
}
package drools
import TraitDonningTest.MyModel
declare MyModel
@Traitable
end
declare trait MyTrait
@PropertyReactive
height : Double
weight : Double
end
rule "1 - Update Model"
when
$model: MyModel(
this['weight'] != null,
this['height'] == null )
then
modify($model) {
put('height', 2.0)};
System.out.println("Rule 1");
end
rule "2 - Apply Trait"
dialect "mvel"
no-loop
when
$model: MyModel(
this['weight'] != null,
this['height'] != null)
then
System.out.println("Rule 2A: " + $model.get('weight') + " (before don)");
MyTrait trait = don($model, MyTrait.class);
System.out.println("Rule 2B: " + $model.get('weight') + " (after don)");
System.out.println("Rule 2C: " + trait.weight );
end
rule "3 - Check Trait"
dialect "mvel"
when
$trait : MyTrait()
then
System.out.println("Rule 3: " + $trait.weight);
end
rule "4 - Check Model"
dialect "mvel"
when
MyTrait()
$model: MyModel()
then
System.out.println("Rule 4A: " + $model.get('height'));
System.out.println("Rule 4B: " + $model.get('weight'));
end
rule "5 - Compute Map"
when
$model : MyModel()
MyTrait(
$height : height,
$weight : weight)
then
double compute = $height + $weight;
modify($model) {
put('bmi', compute)};
System.out.println("Rule 5: " + $model.get('bmi'));
end
rule "6 - Summarize Results"
when
$a: Number() from accumulate( MyModel(), count(1) )
$b: Number() from accumulate( MyTrait(), count(1) )
then
System.out.println("Model: " + $a);
System.out.println("Trait: " + $b);
end
Rule 1
Rule 2A: 1.0 (before don)
Rule 2B: 1.0 (after don)
Rule 2C: 1.0
Rule 3: 1.0
Model: 0
Trait: 1
更多详细信息和测试…
我尝试了几种不同的场景,使用强类型类作为事实而不是映射
如果我将基于地图的事实替换为强类型事实,那么输出将是我所期望的:
Rule 1
Rule 2A: 1.0 (before don)
Rule 2B: 1.0 (after don)
Rule 2C: 1.0
Rule 3: 1.0
Rule 4A: 2.0
Rule 4B: 1.0
Rule 5: 3.0
Model: 1
Trait: 1
如果我使强类型事实(类)扩展HashMap,即使我在trait中有属性,它也会恢复为非工作结果集
Rule 1
Rule 2A: 1.0 (before don)
Rule 2B: 1.0 (after don)
Rule 2C: null
Rule 3: null
Model: 0
Trait: 1
我在上了解了Drools使用组的更多详细信息我在上了解了Drools使用组的更多详细信息