如何比较当前行的属性与Drools中上一行的属性

How to compare attribute of current row to attribute of previous row in Drools

假设我有一个简单的 pojo

    public class foo {
      private String id;
      private Date asOfDate;
      private String product;

      ...getters and setters...
}

我想将一堆 foo 放入规则中,根据日期对它们进行排序,然后将当前产品与之前的产品进行比较。出于这种比较,我想创建一个新事实,其中包含一个名为 ProductChange 的附加属性。 如果当前产品 = 以前的产品,productChange 将设置为 "no change"。如果当前产品 <> 上一个产品,则将其设置为 "change"。

下面是一些示例排序数据:

| id |  asOfDate  | product |
+----+------------+---------+
|  1 | 2017-01-01 | A       |
|  1 | 2017-02-01 | A       |
|  1 | 2017-03-01 | B       |
|  1 | 2017-04-01 | C       |
+----+------------+---------+

新事实如下:

+----+------------+---------+---------------+
| id |  asOfDate  | product | productChange |
+----+------------+---------+---------------+
|  1 | 2017-01-01 | A       | No Change     |
|  1 | 2017-02-01 | A       | No change     |
|  1 | 2017-03-01 | B       | change        |
|  1 | 2017-04-01 | C       | change        |
+----+------------+---------+---------------+

这是我到目前为止在规则中的内容:

rule "compare"
    when 
      $foo : foo ($id : id, $asOfDate : asOfDate, $product : product)
      not foo (asOfDate < $asOfDate)
     then
        System.out.println("id: " + $id + " date: " + $asOfDate + "product: " + $product);
     end

这使集合正确排序,但我不知道如何查看前一行。

最简单的方法是创建 2 个规则:一个用于 2 个连续的 Foos 具有相同的产品,一个用于不具有相同产品的情况。

rule "Same Product"
when 
  $foo1 : foo ($id : id, $asOfDate1 : asOfDate, $product : product)
  $foo2 : foo (asOfDate > $asOfDate1, $asOfDate2:asOfDate, product == $product)
  not foo (asOfDate > $asOfDate, asOfDate < $asOfDate2)  //This will make sure that $foo1 and $foo2 are consecutive
then
    $foo2.setProductChange("No change");
end

rule "Different Product"
when 
  $foo1 : foo ($id : id, $asOfDate1 : asOfDate, $product : product)
  $foo2 : foo (asOfDate > $asOfDate1, $asOfDate2:asOfDate, product != $product)
  not foo (asOfDate > $asOfDate, asOfDate < $asOfDate2)  //This will make sure that $foo1 and $foo2 are consecutive
then
    $foo2.setProductChange("change");
end

请小心,因为这些规则没有考虑具有相同时间戳的不同 Foos。在这种情况下,您需要修改 <> 才能正常工作。

您还需要为第一个 Foo 设置一个单独的规则,或者您可以在第一个规则中添加一个 OR。

希望对您有所帮助,