如何在Drools文件中传递多个对象并提取所需的对象 [英] How to pass multiple objects in a Drools file and extract the desired object

查看:227
本文介绍了如何在Drools文件中传递多个对象并提取所需的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的对Drools陌生.对于一个项目,我试图将多个对象传递到drl文件中,但是我不知道如何在同一规则中处理多个对象!

I'm really new to Drools. For a project I am trying to pass in multiple objects into the drl file but I don't know how to handle multiple objects in the same rule!

这是我的流口水逻辑:

rule "SNAP when Employed"
    
    when
        citizenDataObject: CitizenData(planName=="SNAP" && employed==true)
    then
        PlanData planDataObject= new PlanData();
        planDataObject.setPlanStatus("DN");
        planDataObject.setDenialReason("Salaried Employee");
    end

执行此规则时,无法检索planDataObject.

when I execute this rule I am not able to retrieve the planDataObject.

在Java方面,我正在传递CitizenData对象和PlanData对象:

On java side, I am passing CitizenData object and PlanData object:

WorkingMemory workingMemory = ruleBase.newStatefulSession();
workingMemory.insert(citizenData);
workingMemory.insert(planData);
workingMemory.fireAllRules();

推荐答案

有几种方法可以从规则中获取数据.他们是:

There are several ways of getting data out of your rules. They are:

  1. 调用具有副作用的动作.
  2. 设置/修改全局变量.
  3. 使用事实句柄从工作内存中提取数据.

第一个是最简单的,我建议这样做.第二个是我们过去在过去"时代做的事情.(大约10年前,使用Drools5.)从技术上讲,最后一个可能但非常复杂,我从未做过.

The first is the easiest and the one I would suggest doing. The second is how we used to do it back in the "old days" (10 or so years ago, with Drools 5.) The last is technically possibly but very complex and I've never done it.

我已经在

I've covered all of these in the answer to this other question, which I believe to be a duplicate but can't vote for it as such since it has no upvoted answers.

这是推荐的方法.带有副作用的动作是您所称的,可以在规则之外看到.一个极端的例子可能是保存到数据库,但是一个简单的例子可能是将对象添加到列表.

This is the recommended way of doing this. An action with a side effect is something that you call that can be seen outside of the rules. An extreme example could be saving to a database, but a simpler example might be adding an object to a list.

例如,考虑这种玩具情况.如果学生有3个以上的无故缺勤,则会生成一条便条,并与他们一起送回家给父母.以下是我们可以为这种情况建模的两种方法.一个规则将注释添加到学生对象本身的变量中.另一个规则调用实用程序功能以将笔记发送给父母.第三个将规则添加到注释集合中.

As an example, consider this toy situation. If a student has more than 3 unexcused absences, a note is generated and sent home with them for their parents. The following are two ways we might model this scenario. One rule adds the note to a variable in the student object itself. Another rule calls a utility function to send the note to the parents. The third adds the rule to a collections of notes.

rule "Unexcused absences: notify by adding note to the student record"
when
  $student: Student( absences >= 3, $name: name )
then
  $student.addNote( "Student '" + $name + "' has had too many unexcused absences");
end

rule "Unexcused absences: notify by email"
when
  $student: Student( absences >= 3, $name: name )
  $emailSystem: MailSystem() // Some utility class which can send emails
then
  $emailSystem.sendNote(
    $student,
    "Student '" + $name + "' has had too many unexcused absences"
  );
end

rule "Unexcused absences: append note to a list"
when
  Student( absences >= 3, $name: name )
  $notes: List()
then
  $notes.add("Student '" + $name + "' has had too many unexcused absences.");
end

所有这些规则的工作方式是它们更改外部应用程序(邮件系统)或输入对象(学生或注释列表)中的数据.规则执行完毕后,这些副作用将对外界可见.

The way all of these rules work is that they change the data in either the external application (the mailing system) or the input objects (the student or the list of notes). After the rules finish firing, those side effects will be visible to the outside world.

这是处理全局变量的旧方法.它们通常与Java中的静态变量相同,但是您不能依赖它们来跟踪规则执行之间的数据.(就像使用静态变量和线程一样,规则可见的数据也变得有些复杂.)

This is the old way of doing things, global variables. They're generally the same as static variables in Java, but you must not rely on them to track data between rule executions. (Just like with static variables and threads, what data is visible to the rules gets a little complicated.)

但是,如果我们要做的只是跟踪规则输出,那么这是一个可行的选择.

But if all we want to do is track rule output, this is a viable alternative.

首先,您需要在会话上设置一个全局变量,然后再调用如下规则:

First off, you set a global variable against the session before invoking the rules like this:

KieSession session = ruleBase.newStatefulSession();
session.insert(...); // insert data
session.setGlobal( "myGlobalFoo", value ); // sets the global; note the name must match the rule file!
session.fireAllRules();

然后在规则文件中,使用 global 关键字在文件顶部,导入文件下方声明全局变量.全局名称必须与您传递给 setGlobal 方法的内容完全匹配.

Then in your rule file you'd declare your global at the top of your file, below your imports, using the global keyword. The name of your global must exactly match what you pass in to the setGlobal method.

使用与以前相同的示例(缺席3+次以上的学生将便条寄回家),我们可以按以下方式使用全局变量.在第一个示例中,我们可以使用 List< string>笔记寄回首页的笔记,并将其设置为全局:

Using the same example as before (student with 3+ absences getting a note sent home), we can use a global as follows. In this first example, we can use a List<string> notes of notes sent home, and set that as a global:

global List notes;

rule "Student absences: add note to global List"
when
  Student( absences >= 3, $name: name )
then
  notes.add("Student '" + $name + "' has been absent too many times!");
end

一旦所有规则都被触发,您传递给全局对象将为其添加值.请注意,保留对对象的引用很重要-不要调用 session.setGlobal("notes",new ArrayList<>())之类的东西!您将无法以这种方式引用该注释列表.

Once all the rules are fired, the object that you passed into the global will have the values added to it. Note that it's important that you retain a reference to the object -- don't call something like session.setGlobal("notes", new ArrayList<>())! You'll not have a reference to that notes list that way.

KieSession javadoc 讨论了一些有关全局变量的注意事项,以及一些注意事项.

The KieSession javadoc talks a bit about globals, along with some cautions.

第三种方法是使用事实句柄提取数据.这没有很好的文档记录,我个人还没有做过,但是应该可以的.通常,它用于保持句柄".将一条数据传递到工作内存中,以便您可以将其导出以进行单元测试或其他任何操作.我认为有可能定位和提取新实例化的数据.

The third way is to extract the data using fact handles. This is not well documented and I've not done it personally, but it should be possible. Usually it is used to keep a "handle" on a piece of data being passed into working memory so you can fish it out for unit testing or whatnot. I think it may be possible to target and extract your newly instantiated data.

就我个人而言,我不会走这条路,因为它不是标准的工作流程,并且与Drools库的其他部分相比,围绕这些API的文档很差(因为它主要在内部使用和进行测试.)

Personally I would not go this route since it's not a standard workflow and the documentation around these APIs is poor compared to the other parts of the Drools library (since this is primarily used internally and for testing.)

这篇关于如何在Drools文件中传递多个对象并提取所需的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆