java - Newbee Drools 链表过滤

标签 java drools rule-engine

我对 Drools 还很陌生,但想将它用于我需要解决的案例。

基本上我的规则需要执行以下操作:

  • 根据到人员当前位置的给定距离过滤给定的初始只读(完整)位置列表
  • 创建一个新列表,其中包含给定距离半径内的位置
  • 将新列表移交给下一条规则
  • 根据特定标题过滤新位置列表
  • 创建包含位置的新列表(现在按距离和标题进行过滤)

所以,我想链接几个规则...首先这样做,创建包含结果的新列表,在下一个规则中使用新列表,对其执行进一步过滤,创建包含更多过滤元素的新列表...等等在...

老实说,正如之前提到的,我完全陷入困境,并认为我可以获得一些建议......

我想出的最初规则如下:

package com.acme.rulesets
import com.acme.domain.TopLocation
import com.acme.domain.Person
import com.acme.storage.LocationContainer
import com.acme.helper.GeoHelpers
rule "Get by Distance"
salience 10
when
    $allLocations: LocationContainer()
    $person: Person()
    $loc: TopLocation() from $allLocations.getAllLocations()
then
    double distance = GeoHelpers.getInstance().getHaversineInMiles($person.getLat(), $person.getLon(), $loc.getLat(), $loc.getLon());
    System.out.println($loc.getTitle() + " -- distance in miles to person: " + distance); 
end;

到目前为止,它还没有达到我想要实现的目标......但也许你可以给出一些提示......

所以,首先我认为我需要在规则的 LHS 中调用我的静态 java 方法(它只计算两个给定点之间的距离),但是一旦我(尝试)这样做,它就会编译规则失败。然后我需要使用 $dist 的结果来确定当前条目是否需要放入新列表中(我如何a.)创建一个新列表并b.)将当前条目放入其中?).. ......然后,下一个逻辑步骤将是创建具有更高显着性的新规则“按位置标题获取”并使用新的过滤列表。所以最后,当我回到 java 端时,我可以从工作内存中获取所有列表并用它们做进一步的事情。

是的,我知道,我的问题可能非常n00b-ish......但我找不到任何可以从中得出我的用例的东西。

但是,提前致谢。

最佳答案

我将逐点解决这个问题,而不是尝试提供“完整”的解决方案。您必须决定使用什么。

首先,将所有位置保留在作为单个事实的容器类中可能有充分的理由,但通常,如果容器元素本身就是事实,则规则更容易编写。

rule "person and location"
when
    $p: Person()
    $l: TopLocation(...)
    ...

(当然,您可以坚持使用 from 子句。)

要选择具有特定属性与人员组合的位置:使用任何 boolean 表达式作为约束或评估模式。如果表达式涉及某些静态 Java 函数,请将其导入(就像在 Java 中一样)或将其实现为 DRL 函数。我将结合这三者来说明这一点。

import com.acme.helper.GeoHelpers
function double dist( Person p, TopLocation t ){
    double d =
      GeoHelpers.getInstance().getHaversineInMiles(p.getLat(), p.getLon(),
                                                   t.getLat(), t.getLon());
}

rule "p & l closer than"
when
    $p: Person()
    $l: TopLocation( dist($p,$l) < 100.0 )
    ...

要按更多条件过滤位置,您可以使用附加规则,其中选择满足所需“标题”的位置,但这需要跟踪按距离选择的位置。如果不这样做,只需将“标题”约束添加到规则中即可:

 rule "p & l: Hotel closer than 100"
 when
    $p: Person()
    $l: TopLocation( dist($p,$l) < 100.0,
                     title == "Hotel" )
    ...

等等。

您会说此规则仅适用于单个选择用例 - 如果距离不同或者您正在寻找书店怎么办?

您可以使用参数 block 事实来定义文字。

rule "p & l, X loc closer than D"
when
    Param( $d: distance, $t: title )
    $p: Person()
    $l: TopLocation( dist($p,$l) < $d, title == $t )
    ...

您可能会说这非常好,但是如果选择标准的组合本身发生变化,而不仅仅是值发生变化,该怎么办?那么,当然,拥有单独的规则可能确实更好,每个规则都根据单一标准选择位置。这样,提供参数可以与选择适当的规则相结合,这可以通过多个 Param 子类来完成。另一个问题出现了:如何跟踪选择集。为此,我们可能必须使用另一个辅助事实,我们将其称为ResultSet。假设距离始终是一个标准,我们可以编写如下规则

rule "p & l, closer than D"
when
    $dp: DistParam( $v: distance )
    $p: Person()
    $l: ArrayList() from 
        collect( $l: TopLocation( dist($p,$l) < $v )
then
    retract( $dp );
    insert( new ResultSet( $l ) );
end

rule "p & l, filter by title"
when
    $t: TitleParam( $v: title )
    $r: ResultSet( $s: result )
    $l: ArrayList() from 
        collect( $l: TopLocation( title == $v ) from $s
then
    retract( $t );
    modify( $r ){ setResult($l) }
end

现在可以轻松地任意选择条件,并使用从当前搜索派生的值。 - 您可以在 fireAllRules 返回后使用 API 检索 ResultSet,或者编写另一个规则来处理和收回它。

我建议您研究现有文献。

关于java - Newbee Drools 链表过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35493798/

相关文章:

c++ - 比较 2 个字符串映射的通用 C++ 规则引擎

drools - 使用带有动态决策表的drools专家

java - JDBC 问题 : not being able to correctly bind variables and values (shortened)

java - Drools Planner 构造启发式 java.lang.ClassCastException

gwt - 流口水 Maven 依赖与 GWT 冲突

java - 流口水;在另一台机器上执行时无法加载pom.properties

java - 用Java编写的开源规则引擎

java - 返回 FileInputStream 指向的旧位置

java - 筛选并上传 Java 类在本地工作,但不能在线工作。没有任何错误。怎么了?

java - jOOQ转换器在写入记录时隐式设置一个值