当前位置: 首页 > 知识库问答 >
问题:

Drools-当部件抛出错误时,将dsl中的多个dsl条件分组

狄新翰
2023-03-14

我正在创建一个小型规则引擎,并为其使用drools。我的设计就像开发人员(即我:)将开发dsl,而业务用户可以创建规则(dslr)。

dsl文件

[When]When [Pp]urchase amount is greater than "{Value}" = e : Event(EventAction.isPurchaseGreaterThan(e,{Value}))
[When]If [Cc]ustomer tier equals to "{CustomerTier}"=e1 : Event(EventAction.isCustomerTierEqualTo(e1,"{CustomerTier}")
[Then]Give "{Discount}" Percentage Discount = RewardAction.applyDiscount(e, {Discount});
[Then]Suggest Redemption = System.out.println("Redemption Suggested");

dslr文件

rule "Discount For Purchase-1"
    when (When purchase amount is greater than "100") && (If customer tier equals to "Silver")
    then     #Error is thrown in this line
        Give "5" Percentage Discount 
end 

其余的java代码与示例中给出的代码类似。在此代码中,我得到以下错误

错误

Line 15:4 mismatched input 'then' in rule "Discount For Purchase-1"

而下面的单反效果很好

rule "Discount For Purchase-1"
    when (When purchase amount is greater than "100")
    then
        Give "5" Percentage Discount 
end 

生成的DRL

when (e : Event(EventAction.isPurchaseGreaterThan(e,100))) && (e : Event(EventAction.isCustomerTierEqualTo(e,"Silver"))

注意这个生成的DRL-我可能会得到“e”的重复变量错误。这是另一个问题。但为了解决这个问题,我甚至尝试将dsl中的第二个变量修改为“e1”。

为了给你提供信息,我尝试了以下方法来解决这个错误,但没有任何帮助

When (When purchase amount is greater than "100" && If customer tier equals to "Silver")
When (When purchase amount is greater than "100" and If customer tier equals to "Silver")
When ((When purchase amount is greater than "100") && (If customer tier equals to "Silver"))
When ((When purchase amount is greater than "100") and (If customer tier equals to "Silver"))
When ((When purchase amount is greater than "100") and (If customer tier equals to "Silver"));
When ((When purchase amount is greater than "100") && (If customer tier equals to "Silver"));

更新:

生成的drl

=== DRL xpanded from DSLR ===
   1  #created on: 5 Oct, 2016
   2  package com.test.loyalty.rules
   3  
   4  #list any import classes here.
   5  import com.test.loyalty.*
   6  import com.test.loyalty.model.*
   7  import com.test.loyalty.util.*
   8  
   9  
  10  
  11  #declare any global variables here
  12  
  13  rule "Discount For Purchase-1"
  14      when 
  15        e : Event(EventAction.isPurchaseGreaterThan(e,100))
  16        e1 : Event(EventAction.isCustomerTierEqualTo(e1,"Silver")
  17      then
  18          System.out.println("Redemption Suggested"); 
  19  end
  20  
  21  rule "Discount For Purchase-2"
  22      when
  23          e : Event(EventAction.isPurchaseGreaterThan(e,100))
  24        e1 : Event(EventAction.isCustomerTierEqualTo(e1,"Gold")
  25      then
  26          System.out.println("Redemption Suggested"); 
  27  end
  28  


=============================
[ERR 102] Line 17:4 mismatched input 'then' in rule "Discount For Purchase-1"
17
[ERR 102] Line 25:4 mismatched input 'then' in rule "Discount For Purchase-2"
25
java.lang.IllegalArgumentException: Could not parse knowledge.
    at com.test.loyalty.LoyaltyTest.readKnowledgeBase(LoyaltyTest.java:124)
    at com.test.loyalty.LoyaltyTest.init(LoyaltyTest.java:104)
    at com.test.loyalty.LoyaltyTest.main(LoyaltyTest.java:38)

有人能帮我吗?先谢谢你。

共有2个答案

缪征
2023-03-14

我认为您的值100中的引号“”有问题。尝试重写为

When]When [Pp]urchase amount is greater than {Value} = = e : Event(EventAction.isPurchaseGreaterThan(e,"{Value}"));

在编写规则时,不需要插入引号。如果您的值是String,那么这当然是真的。如果是int,则排除引号。另一个建议是,为了查看您的规则是否被转换,您应该插入

调试:显示结果

在dsl文件的开头和结尾。

慕才
2023-03-14

您将在顶层组合两种模式(使用类EventAction),因此不需要运算符,并且

rule "Discount For Purchase-1"
when
    When purchase amount is greater than "100"
    If customer tier equals to "Silver"
then    
    Give "5" Percentage Discount 
end 

我想知道您是否真的考虑了两个Event-s的组合。如果没有,最好将约束组合在一个模式中——尽管这有点棘手。(参见文档。)或者,您确实可以通过在附加约束中使用this==e之类的东西来强制绑定到第二个模式(同一类)的另一个事实的标识。

添加了扩展文本后进行编辑,它很突出:Event(EventAction.isCustomerTierEqualTo(e1,“Silver”)在末尾缺少一个右括号,在另一条规则中也是如此。修复DSL中的替换规则。

可以在任意数量的规则中使用相同的变量,但不能将同一规则中的两个模式绑定到同一个变量。您可能需要重新设计一点DSL,例如:。

# creates the Person pattern and binds $person
[condition][]There is a Person with=$person:Person()

# write a comparison using a field reference and a value
[condition][]- his {field} {operator} {value}=
             {field} {operator} {value}

数码单反成为:

when
    There is a Person with
    - his call_count is less than 10 or name is equal to "Joe" 
    - his points is greater than 5
then

扩展到

when
    $person:Person(call_count  <  10 || name == "Joe", points  >  5)
then

当然,您需要运算符(或您的函数)的定义

[condition][]is greater than=>
[condition][]is equal to===

开头的连字符是必不可少的,您需要在第一个参数({field})前面加上一些东西(“his”或“her”)。

 类似资料:
  • 例 {field}>{Staic值}或{field1}>{field2} 我可以编写以下两个规则来实现这一点,但我的意图是编写一个规则来匹配这两个标准。

  • 想项目中添加插件的新方法不仅仅是一种更为方便的语法.新的DSL语法处理与老方法有很大的不同.新的机制允许Gradle更早更快的确定插件.这允许做更智能的事,如: 优化插件类的加载和重用. 允许不同的插件使用不同版本的依赖关系. 为编辑构建脚本提供关于隐含属性和值的详细信息 这要求插件被指定使Gradle在执行之前剩下的构建脚本前可以很容易并且很快的提取它.还要求插件使用一些静态的定义。 新的插件机

  • 当我在Kibana开发控制台上运行下面的弹性搜索DSL查询时,它会正确返回结果,我试图通过基于URI的查询运行相同的结果,因为HTTP URL不起作用。我尝试了doc和良好的搜索,没有得到确切的方式来帧这个查询为基于HTTP的GET网址。 有什么提示吗。

  • 我是apache camel和restlet组件新手。 有人能帮忙吗。

  • 我在使用elasticsearch dsl删除项目时遇到问题。当我试图过滤我的数据时,它很容易,像这样的东西效果很好。 扫描也可以: 但是当我想删除这样的项目时: 我出错了:

  • 我正在尝试使用ShadowJar构建一个fatjar。我的应用程序和gradle代码如下。我使用Gradle 5.0进行构建。当我运行./gradlew run时,代码运行正常。当我运行“gradle shadowjar”并使用“build/lib”文件夹中的“java-jar”运行fatjar时,我得到了以下错误。 我猜依赖项没有加载到fatjar中?我还使用Groovy构建了Gradle文件,