drools RHS не оценивается должным образом

#dynamic #conditional-statements #drools

#динамический #условные операторы #пускает слюни

Вопрос:

У меня есть POJO, определенный как показано ниже

 public MyClass{
String batchId
String id;
List<Cols> cols;
}

public Cols {
BigDecimal colA;
BigDecimal colB;
BigDecimal colC;
}
  

Теперь у меня есть правило drools, как показано ниже

 rule "myrule"
when
$f : MyClass() //full
$v : Cols(batchId!=null) from $f.cols
$h : Cols(batchId!=null amp;amp; func(colaA, colB, colC, true)) from $f.cols //subset of $v with additional constraints
then
$f.addResults("myrule",$v, $h)
end
  

«myrule» компилируется и выполняется, если в $ h генерируется значение. Что мне нужно, так это то, что если есть ненулевой $ v, то он должен выполняться всегда с необязательным значением $ h..

Этот вариант использования предназначен для приложения для проверки качества данных, где мы пытаемся определить, следует ли сначала запускать это правило для факта, и если это допустимые факты (BatchID НЕ равен NULL), то проверяйте выражение в $ h. Если $ h там нет, то $ v рассматривается как пропуск. Если значение $ h НЕ равно NULL, то значение $ v рассматривается как FAIL, и соответствующий результат добавляется к $ f (уровень факта).

Когда я запускаю этот случай, правило выполняется и добавляет результаты, только если значение $ h НЕ равно NULL.

Как добавить результаты для $ v, даже если нет $ h?

Комментарии:

1. Неясно, в чем заключается ваша реальная проблема. В соответствии с вашим вариантом использования, если $ h не равно null, то $ v является ошибкой, и вы вызываете addResults. Если $ h равно нулю, это не сбой, и правило не срабатывает. Для меня это звучит правильно, и это соответствует тому, что вы реализовали.

2. Также ваше правило никак не компилируется и не выполняется, потому что вы пытаетесь проверить значение BatchID в классе Cols, в котором не определена такая переменная или метод.

Ответ №1:

Ваш POJO не соответствует вашему правилу, и ни один из них не соответствует вашему варианту использования, поэтому я понятия не имею, что вы на самом деле делаете.

Но, если я вас правильно понимаю, вам нужно, чтобы ваше правило срабатывало независимо от наличия $h , хотя $h на самом деле это необходимо с правой стороны.

Для этого вам нужны два правила. Один для того, когда $h существует, и один для того, когда $h нет.

Когда $h существует, ваше существующее правило работает нормально. Или, это будет работать нормально, если ваш POJO обновлен в соответствии с вашим правилом или ваше правило обновлено в соответствии с вашим POJO. (Ваше правило проверяет, что BatchID в вашем классе Cols равен null; в вашем классе Cols нет BatchID.)

Вторым правилом было бы, когда нет $h . Поскольку я понятия не имею, что такое ваш addResults метод или как он реализован, я предполагаю, что вы передали бы null или пустой список вместо $h переменной этому методу. Вы можете проверить, что нет, $h используя not(...) выражение с левой стороны.


Используя ваши POJO и игнорируя правило, которое вы предоставили, я бы реализовал это следующим образом:

 // This is the existing rule, updated to match the POJO
rule "myrule with $h"
when
  $f: MyClass( batchId != null, // batchId is on MyClass, not Cols
               $v: cols != null )
  
  // Per the comments, $h is supposed to be a subset of $v
  // The "additional constraints" are implemented as a not-null check for demo purposes
  $h: List(size > 0) from collect(Cols( colA != null, colB != null, colC != null ) from $v) 
then
  $f.addResult("myrule", $v, $h);
end

rule "myrule with no $h"
when
  $f: MyClass( batchId != null,
               $v: cols != null )

  // check that there are no Cols that match the additional constraint inside of $v
  not( Cols( colA != null, colB != null, colC != null ) from $v)
then
  // set an empty list as $h in the addResults method
  $f.addResult("myrule", $v, Collections.emptyList());
end