[rules-users] how to count distinct nested property?
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) { SetInteger myIds = new HashSetInteger(); 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
Re: [rules-users] how to count distinct nested property?
I wonder if something like this might do it? when $set : HashSet ( ) from accumulate ( ObjectA ( $myId : objectC.myId ), init ( HashSet uniqueIds = new HashSetString(); ), 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.ha...@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) { SetInteger myIds = new HashSetInteger(); 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 ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] how to count distinct nested property?
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@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 HashSetString(); ), 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.ha...@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) { SetInteger myIds = new HashSetInteger(); 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 ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] how to count distinct nested property?
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@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@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 HashSetString(); ), 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.ha...@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) { SetInteger myIds = new HashSetInteger(); 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 ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users