My last comparison there may be problematic as well...too focused on the accumulate to see the obvious. I think that approach might still require an eval to check the size constraint on the list and we don't really want that. 

What you could do instead, however, is insert the hashset into the working memory in that rule's consequence and have a 2nd rule that's just HashSet ( size > 1 ) and its consequence does your actions and retracts the hashset back out of memory.

- J


On Tue, Jul 22, 2014 at 9:39 AM, Jeremy Ary <jeremy.ary@gmail.com> wrote:
err, typo there, add() and remove() should be using $myId instead of $id


On Tue, Jul 22, 2014 at 9:38 AM, Jeremy Ary <jeremy.ary@gmail.com> wrote:
I wonder if something like this might do it?
when
    $set : HashSet ( ) from  accumulate ( ObjectA ( $myId : objectC.myId ),
                              init ( HashSet uniqueIds = new HashSet<String>(); ),
                              action ( uniqueIds.add($id); ),
                              reverse ( uniqueIds.remove($id); ),
                              result ( uniqueIds ) )
    HashSet ( this == $set, size > 1 )
then
    // consequence
end

- Jeremy


On Tue, Jul 22, 2014 at 8:42 AM, richardhands <richard.hands@uk.sopragroup.com> wrote:
Hi,

I’m trying to wrap my head around how to use a combination of accumulate
from and collect from to get a count of how many unique items there are of a
nested child property and run the RHS of a rule if it’s > 1

So I have

Many of Object A

Each one contains
An object B
An object C

Object C contains a nested child property

So

A
+-+-B
   |
   +-C – property myId

(many of these in the working memory)

The rule I’m working with right now is

rule "B must only be at 1 myId per day"
    when
      $b : B()
      $c : C()
      $aList : ArrayList (size > 1)
        from collect(
              A(b == $b, c.getDate() == $c.getDate()) )
      eval ( RulesUtils.countIdsForC ($aList) > 1 )
   then
     //fire some rules here
end

and the RulesUtils method is

  public static int countIdsForC (List  aList)
  {
    Set<Integer> myIds = new HashSet<Integer>();
    for (A a : aList)
    {
      myIds.add(a.getC().getMyId());
    }
    return myIds.size();
  }


Now I’m well aware that this is sub-optimal, and indeed is firing lots of
extra times and is really (Really) slow.  I can vizualise that this should
easily be possible with some combination of compound accumulate and collect
statements, but for the life of me I can’t work out the correct arrangement
(This is actually for use in an optaplanner ruleset so it will potentially
be working on lots of data, over many iterations).

Any suggestions on how to do this the way I know it needs to be, greatfully
appreciated 




--
View this message in context: http://drools.46999.n3.nabble.com/how-to-count-distinct-nested-property-tp4030424.html
Sent from the Drools: User forum mailing list archive at Nabble.com.

_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users