Java 如何访问drools中自定义对象的映射

Java 如何访问drools中自定义对象的映射,java,drools,rule-engine,Java,Drools,Rule Engine,我有以下Drools规则文件,我将填充了自定义对象(NodeElement)的map发送到该文件,map是一个全局变量,因为它必须被所有规则访问,还有另一个全局变量错误,当规则失败时会填充该错误。我已经使用了eval,并且能够成功地执行它。在做了一些研究之后,发现eval有一些性能问题 我的问题是 1) 性能问题可以忽略吗 2) 使用eval是一种良好的实践吗 3) 如果我必须重写这些规则?哪种方法最好 import java.util.Map; import com.infodev.pojo.

我有以下Drools规则文件,我将填充了自定义对象(NodeElement)的map发送到该文件,map是一个全局变量,因为它必须被所有规则访问,还有另一个全局变量错误,当规则失败时会填充该错误。我已经使用了eval,并且能够成功地执行它。在做了一些研究之后,发现eval有一些性能问题

我的问题是

1) 性能问题可以忽略吗

2) 使用eval是一种良好的实践吗

3) 如果我必须重写这些规则?哪种方法最好

import java.util.Map;
import com.infodev.pojo.NodeElement;
import com.main.Errors;
import com.validation.DateValidation;

global java.util.Map map;
global com.main.Errors errors;


rule "Fixed / Floating ccy rule"

    when
        eval(!((NodeElement)map.get("FixedCurrency")).getValue().equals(((NodeElement)map.get("FloatingCurrency")).getValue()))
    then 
        errors.addError( "Currency", "Fixed currency should be same as Floating currency" );
end

rule "Payment / Settlement date rule"

    when
        eval(!(DateValidation.paymentDateValidation(((NodeElement)map.get("tradeDate")).getValue(),((NodeElement)map.get("paymentDate")).getValue())))

    then 
        errors.addError(map.get("paymentDate").toString(), "Payment date should be after trade date" );

end
地图是:

Map<String, NodeElement> map = new HashMap<String, NodeElement>();
    map.put("FixedCurrency", new NodeElement("FixedCurrency", "USD"));
    map.put("FloatingCurrency", new NodeElement("FloatingCurrency", "UD"));
    map.put("tradeDate", new NodeElement("tradeDate", "2012-01-22"));
    map.put("paymentDate",new NodeElement("paymentDate", "2012-01-2"));
Map Map=newhashmap();
map.put(“固定货币”,新节点元素(“固定货币”,“美元”);
map.put(“浮动货币”,新节点元素(“浮动货币”,“UD”);
地图出售(“交易日期”,新节点元素(“交易日期”,“2012-01-22”);
地图出售(“付款日期”,新节点元素(“付款日期”,“2012-01-2”);
您没有规则,您有if语句(伪装成规则)处理映射对象和其他静态对象中的值。(为什么不在添加到地图后运行这些检查??)

在你的规则中,我看不到任何
eval


如果需要
eval
,则必须使用
eval
,如果可以避免,请避免它。

既然可以使用与映射键相同的字符串来识别节点元素,为什么不直接将节点元素插入会话?通过这样做,您可以像这样重写规则:

rule "Fixed / Floating ccy rule"
when
    $n1: NodeElement( id == "FixedCurrency")
    $n2: NodeElement( id == "FloatingCurrency", value != $n1.value)
then
    errors.addError( "Currency", "Fixed currency should be same as Floating currency" );
end

rule "Payment / Settlement date rule"
when
    $n1: NodeElement( id == "tradeDate")
    $n2: NodeElement( id == "paymentDate", value != $n1.value)
    eval(!(DateValidation.paymentDateValidation($n1.value, $n2.value)))
then
    errors.addError($n2.value.toString(), "Payment date should be after trade date" );
end
我不能告诉你,像这样重新编写规则是否会提高性能。这也将取决于其他因素。我认为,通过这种新方法,您确实可以获得可读性


希望能有所帮助,

很抱歉,那些if实际上是在评估。而且不确定你们在地图添加后说“检查”意味着什么,意思是“使用if-else”而不是“drools本身”?。。。上面的规则可能很简单,可以用if-else解决,但是我的实际规则会很复杂。你能给我指出一个正确的方向,不使用eval就可以做到这一点吗?在这些“规则”中,你不能访问工作记忆中的任何事实,所以你在那里编码的只是一个if语句。是的,您可以将这些检查作为Java代码中的Java if语句运行,就在那些
map.put(…)
语句之后。-现在编写它们时,必须使用
eval
。如果它们更复杂,那么在规则的伪装下,它们只会变得更复杂。如果它们都是这样的,只访问几个静态对象,你就失去了生产规则系统的全部意义,可以继续使用Java。这里显示的映射是一个静态内容,但实际上生成的映射将是一个键的集合,xml文档中的值对,其中key是xml标记,value是该标记的值。是否要在此映射上运行一些业务规则以检查xml文档是否为有效文档?。这是我的用例。当你说事实时,是指工作内存中传递给drools的java对象,对吗?。如果是这样的话,那么我们不能使用map对象而不是java类对象吗?的确,大多数规则都是复杂的if语句,但我认为drools在某些方面可以帮助你。你可能会陷入混乱的代码中。XML标记用于标识任意数据对象。如果您使用类似JAXB或更好的工具来解组XML文档,那么您就有了一个很好的对象层次结构,而将其扔掉通常会很遗憾(除非您有一个非常扁平的同类元素结构)。Google“使用XML数据进行推理”并阅读第2章。同意你的观点,是的,我们正在研究一个非常扁平的元素结构,你的论文“使用XML数据进行推理”内容非常丰富,帮助我们解决了一些问题。谢谢。为什么不全力以赴使用
FixedCurrency
TradeDate
等作为类型名称呢。这将使它真正具有可读性;-)谢谢,这很有效。但只要问问有没有更好的方法?能否更有效地实现这一目标?