在 Drools 中传递多个对象不起作用

Passing multiple objects in Drools not working

我创建了一个有状态的知识会话,我用它在会话中插入多个对象。

StatefulKnowledgeSession ksession = initializeDrools(runtimeDrlFile.getFilePath());

private StatefulKnowledgeSession initializeDrools(String filePath) throws Exception {
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add(ResourceFactory.newFileResource("E:\drools\" + filePath), ResourceType.DRL);
    KnowledgeBase kbase = kbuilder.newKnowledgeBase();
    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
    return kbase.newStatefulKnowledgeSession();
}

假设我有两张地图,例如

Map<String, Object> map  = new HashMap<String, Object>();  // Assume somthing is stored in it
Map<String, Object> maps = new HashMap<String, Object>();  //   ""

现在我已将两个对象都插入到 ksession 中并触发了所有规则。

ksession.insert(maps);
ksession.insert(map);
ksession.fireAllRules();

这是我的 drools 文件。

import java.util.Map;

rule "Category Level"

when
    $map: Map( this["CategoryCode"] == "10" && this["CategoryAmount"] >= 1000 )
then
    $map.put("Discount", String.valueOf("10.00"));
    System.out.println($map);
    System.out.println($maps);
end 

显示我是

Caused by: java.lang.IllegalArgumentException: Could not parse knowledge.

如果我删除 System.out.println($maps);,它会正常工作。如果我在 drl 文件中将所有出现的 $map 替换为 $maps,它也可以正常工作,但现在我无法访问 $map,反之亦然。

我将多个对象传递给流口水的逻辑有什么问题吗?

更新:

清除非法参数异常后,

import java.util.Map;

rule "Category Level"

when
    $maps: Map()
    $map: Map( this["CategoryCode"] == "10" && this["CategoryAmount"] >= 1000 )
then
    $map.put("Discount", String.valueOf("10.00"));
    System.out.println($map);
    System.out.println($maps);
end 

现在的问题是 sysout 正在打印 $map 的值。为什么 $maps 值被替换为 $map

您没有在任何地方定义 $maps。您需要声明它并为其赋值。

你想要这样的东西:

$map: Map( this["CategoryCode"] == "10" && this["CategoryAmount"] >= 1000 )
$maps: Map()

类似

的模式
$mx: Map()

能够绑定作为事实插入的任何地图。所以,如果你有几个模式

$mx: Map()
$my: Map()

单个地图将绑定为 $mx 和 $my。如果您有两个地图 a 和 b,它们将以四重方式绑定:a-a、a-b、b-a、b-b.

向模式添加约束,例如,

$mx: Map( this["CategoryCode"] == "10" && this["CategoryAmount"] >= 1000 )

限制可能的匹配和绑定,但添加另一个模式:

$mx: Map( this["CategoryCode"] == "10" && this["CategoryAmount"] >= 1000 )
$my: Map()

仍会产生多个匹配项,例如,将两个地图作为事实,其中一个地图与第一个模式匹配,您仍然会得到 a-a、a-b.

java.util.Map 和其他 "anonymous" 容器 类(地图和所有 Collections)是出了名的难以匹配。如果地图表示某个 "real world" 实体,则它应该有一个提供唯一标识的条目。在所有模式中使用它。

最好,Java beans 应该用作事实,一些字段提供标识。