drools query

查询是在工作内存中搜索符合所述条件的事实的简单方法。因此,它只包含规则的LHS结构,因此既不指定“when”也不指定“then”。查询具有一组可选参数,每个参数都可以选择键入。如果未给出类型,则假定为Object类型。Drools引擎将尝试根据需要强制执行值。查询名称是KieBase的全局名称; 所以不要将相同名称的查询添加到同一RuleBase的不同包中。

要返回结果,请使用ksession.getQueryResults("name")“name”作为查询的名称。这将返回一个查询结果列表,允许您检索与查询匹配的对象。

第一个示例为30岁以上的所有人提供简单查询。第二个示例使用参数将年龄限制与位置相结合。

query "people over the age of 30"
    person : Person( age > 30 )
end
query "people over the age of x"  (int x, String y)
    person : Person( age > x, location == y )
end

我们使用标准的“for”循环遍历返回的QueryResults。每个元素都是QueryResultsRow,我们可以使用它来访问元组中的每个列。可以通过绑定声明名称或索引位置访问这些列。

QueryResults results = ksession.getQueryResults( "people over the age of 30" );
System.out.println( "we have " + results.size() + " people over the age  of 30" );

System.out.println( "These people are are over 30:" );

for ( QueryResultsRow row : results ) {
    Person person = ( Person ) row.get( "person" );
    System.out.println( person.getName() + "\n" );
}

为更紧凑的代码添加了对位置语法的支持。默认情况下,类型声明中声明的类型顺序与参数位置匹配。但是可以使用@position注释覆盖它们。这允许模式与位置参数一起使用,而不是更详细的命名参数。

declare Cheese
    name : String @position(1)
    shop : String @position(2)
    price : int @position(0)
end

org.drools.definition.type包中的@Position注释可用于在类路径上注释原始pojos。目前,只能对类上的字段进行注释。支持类的继承,但不支持接口或方法。下面的isContainedIn查询演示了在模式中使用位置参数; Location(x, y;)代替Location( thing == x, location == y).

查询现在可以调用其他查询,这与可选的查询参数相结合,提供了派生查询样式的反向链接。参数支持位置和命名语法。也可以混合位置和命名,但位置必须首先,由分号分隔。文字表达式可以作为查询参数传递,但在此阶段您不能将表达式与变量混合。以下是调用另一个查询的查询示例。请注意,此处的“z”始终为“out”变量。'?' 符号表示查询仅为拉取,一旦返回结果,您将无法在基础数据更改时收到进一步的结果。

declare Location
    thing : String
    location : String
end

query isContainedIn( String x, String y )
    Location(x, y;)
    or
    ( Location(z, y;) and ?isContainedIn(x, z;) )
end

如前所述,您可以使用实时“开放”查询来反复接收查询结果随时间的变化,因为它查询的基础数据会发生变化。请注意,“look”规则在不使用“?”的情况下调用查询。

query isContainedIn( String x, String y )
    Location(x, y;)
    or
    ( Location(z, y;) and isContainedIn(x, z;) )
end

rule look when
    Person( $l : likes )
    isContainedIn( $l, 'office'; )
then
   insertLogical( $l 'is in the office' );
end

Drools支持派生查询的统一,简而言之,这意味着参数是可选的。可以使用静态字段org.drools.core.runtime.rule.Variable.v从Java调用查询而不指定参数 - 请注意,您必须使用'v'而不是Variable的替代实例。这些被称为'out'参数。请注意,查询本身不会在编译时声明参数是进入还是出现,这可以在每次使用时纯粹在运行时定义。以下示例将返回office中包含的所有对象。

results = ksession.getQueryResults( "isContainedIn", new Object[] {  Variable.v, "office" } );
l = new ArrayList<List<String>>();
for ( QueryResultsRow r : results ) {
    l.add( Arrays.asList( new String[] { (String) r.get( "x" ), (String) r.get( "y" ) } ) );
}

该算法使用堆栈来处理递归,因此方法堆栈不会爆炸。

也可以使用查询的输入参数作为fact的字段,如:

扫描二维码关注公众号,回复: 6793374 查看本文章
query contains(String $s, String $c)
    $s := String( this.contains( $c ) )
end

rule PersonNamesWithA when
    $p : Person()
    contains( $p.name, "a"; )
then
end

以及更多通常的任何类型的有效表达式,如:

query checkLength(String $s, int $l)
    $s := String( length == $l )
end

rule CheckPersonNameLength 
when
    $i : Integer()
    $p : Person()
    checkLength( $p.name, 1 + $i + $p.age; )
then
end

以下内容尚不支持:

  • List and Map统一

  • 表达统一 - pred(X,X + 1,X * Y / 7)

猜你喜欢

转载自blog.csdn.net/top_explore/article/details/93879387