'Drools-Equivalent of the "not in" SQL

I have two tables A and B. I want to update column A in table A if it doesn't have a match with column B in table B.

I've written the following, but it doesn't work.

rule "Lookup"

when
  B($colB: colB)
  $a : A($colB not contains colA)

then 
  modify($a){
   setcolA(1000)
 }
end

I've tried using accumulate as well but in vain. Any suggestions are highly appreciated.

Equivalent in SQL is

Update colA set colA =1000 from A where colA not in (Select colB from B)


Solution 1:[1]

As I mentioned in a comment, this depends on what data types colA and colB.

But let's say we have something like this:

class Person {
  String name;
}

class Cohort {
  List<String> names;
}

And what you want to do is add the person's name to the list of names in the cohort if the name isn't already present. (This is obviously a contrived example since the Real World solution would be to use a Set, not a List, but this is for illustrative purposes only.)

Now we can write a rule that tests if the name is not present like this:

rule "Add person to cohort"
when
  Person( $name: name )
  $cohort: Cohort( names not contains $name )
then
  // make the modification here
end

Note that in addition to contains/not contains, there's also a memberOf/not memberOf pair of operators. Which one you use depends on whether you're testing that a field is part of a collection, or a collection contains a field.

For completeness's sake, you might use memberOf like this:

rule "At least one person is not in the cohort"
when
  Cohort( $names: names )
  exists( Person( name not memberOf $names ) )
then
  // there exists at least one Person whose name is not in the cohort's name list
end

Further, if your list is hard-coded, we even have in/not in operators.

rule "Shirt color not valid"
when
  Shirt( color not in ("red", "blue", "green"))
then
  // the shirt color is some other color, eg "yellow"
end

rule "Unable to ship to country"
when
  Order( country in ("Canada", "Puerto Rico") )
then
  //
end

Of course, the contains version a lot like your example which "doesn't work", which makes me think that your data types are not an object plus a collection. Maybe you're trying to find an intersection of two collections -- that's a different sort of algorithm which you could implement using accumulate and collect.

But for the question as-is, these three sets of operators (contains/not contains ; memberOf/not memberOf ; and in/not in) are the three ways you can figure out if an item is present in a collection.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Roddy of the Frozen Peas