Drools Don';忽略一个特征会使基于地图的事实变得松散

Drools Don';忽略一个特征会使基于地图的事实变得松散,drools,Drools,当我们试图将一个特征“don”到基于地图的模型时,我们遇到了流口水的问题 似乎在不使用特征后,基于地图的事实会消失(或收回)。 使用trait属性访问模型属性似乎没有任何问题 在以下场景中,预期为: 将向引擎提供一个填充的基于地图的事实 我们根据规则中的约束修改基于地图的事实 我们根据映射事实检查约束,并应用特征 我们在后续规则中使用特征和模型 在规则5中,无论我是否向trait添加“bmi”属性并尝试设置该属性和/或将该属性放入基于地图的事实中,它仍然没有达到此规则(或规则3之后的任何内容)

当我们试图将一个特征“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使用组的更多详细信息