【问题标题】:How can i match on multiple objects of the same kind in Drools 5?如何在 Drools 5 中匹配多个相同类型的对象?
【发布时间】:2017-11-09 21:27:18
【问题描述】:

鉴于内存中有两个或更多 BMSContract 对象的集合,我需要使用 BMSContract.status 字段匹配特定模式。如果在此类集合中只有一个且只有一个 BMSCContract 的状态为 ACTIVE,我的规则应该解析为 Success。对象和状态代码的任何其他组合都应解析为失败。同样,此规则仅适用于 2 个或更多对象的集合,并且可以有任意数量:2、5、10、15 或更多。管理单个 BMSCContract 记录的规则集略有不同。这些规则仅适用于多个记录场景,例如:

Case1 - Success
BMSContract(status=ACTIVE)
BMSContract(status=PENDING)
Reason:  only one Active in the collection

Case2 - Success
BMSContract(status=ACTIVE)
BMSContract(status=PENDING)
BMSContract(status=HOLD)
Reason: only one Active in the coll

Case3 - Success
BMSContract(status=ACTIVE)
BMSContract(status=PENDING)
BMSContract(status=HOLD)
BMSContract(status=CANCEL)
Reason:  only one Active in the coll

Case4 - Failure
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
Reason:  too many Active records in coll

Case5 - Failure
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
Reason:  too many Active records in coll

Case6 - Failure
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
Reason:  too many Active records in coll

Case7 - Failure
BMSContract(status=PENDING)
BMSContract(status=HOLD)
BMSContract(status=OTHER)
Reason:  No Active records in coll

【问题讨论】:

    标签: drools rules business-rules


    【解决方案1】:

    鉴于您有许多 BMSContract 事实,以下规则就足够了:

    rule OK
    when
      $ac: BMSContract( status == "ACTIVE" )
      not BMSContract( this != $ac, status == "ACTIVE" )
    then
      // there is exactly one ACTIVE
    end
    
    rule not_OK_1
    when
      not BMSContract( status == "ACTIVE" )
    then
      // there is no ACTIVE
    end
    
    rule not_OK_2
    when
      $ac: BMSContract( status == "ACTIVE" )
      exists BMSContract( this != $ac, status == "ACTIVE" )
    then
      // there is more than one ACTIVE
    end
    

    变体是可能的,如果您需要确定引起问题的事实,可能需要这些变体:

    rule not_OK_2a
    when
      $ac1: BMSContract( status == "ACTIVE" )
      $ac2: BMSContract( this != $ac, status == "ACTIVE" )
    then
      // log and retract $ac2
    end
    

    【讨论】:

    • q1:不理解这个语法:不是 BMSContract(this != $ac, status == "ACTIVE") q2:我应该将 BMSContract 对象作为单个对象还是作为集合声明到工作内存中?
    • CE not 是否定存在量词的语法,∄。 -- 如果您不将所有BMSContract 对象作为单独的事实插入,事情会很复杂,因为您必须拥有一个带有List<BMSContract> 的容器并使用from 来扩展每个模式的列表。除非有令人信服的理由,否则我不建议这样做。
    • 我还是不明白 : this != $ac 的意思。这 != $ac 是什么意思?这是否意味着此实例与绑定到 $ac 变量的实例不同?
    • 很抱歉 - 我需要更改我原来的问题。我现在有更多信息,但情况有点不同。
    • 使用 `this != $ac` 可以避免第二个模式匹配相同的事实。 -- 我仍然坚持我的规则集可以检测到您问题中给出的所有故障。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    • 2017-05-12
    • 1970-01-01
    相关资源
    最近更新 更多