Re: [rules-users] Finding matching values in composite constraint
(1) It could be possible to create distinct rules, each rule matching just one single potential substring - but I would not do that. (2) It's better to insert the substrings that should be detected in the transaction field as individual objects of a class Key: public class Key { String key; public Key( String key ){ this.key = key; } public String getKey(){ return key; } public boolean matches( String field ){ return field.contains( key ); } } with a simple rule: rule r1 when $key: Key() $t: Transaction( $code: code, eval( $key.matches( $code ) ) ) then System.out.println( '"' + $code + "\" matches \"" + $key.getKey() + '"'); end (3) If you absolutely want to have the potential matches in the rule text you can use a helper class Multikey public class Multikey { private static Map field2key = new HashMap(); public static boolean matches( String field, String... keys ){ for( String key: keys ){ if( field.contains( key ) ){ field2key.put( field, key ); return true; } } return false; } public static String matchingKey( String field ){ return field2key.get( field ); } } and the rule would be: rule r2 when Transaction( $code: code ) eval( Multikey.matches( $code, "foo", "bar", "plan" ) ) then System.out.println( '"' + $code + "\" matches \"" + Multikey.matchingKey( $code ) + '"' ); end Some strategy for removing Map entries may have to be devised; that would depend on the application scenario. -W On 05/01/2013, Jeremy Ary wrote: > Reading it back over, I can simplify this a bit if we're solely dealing > with strings... > > ... > > public class Transaction { > > private String field; > > // ... getter and setter for field, as well as all your other > methods in transaction, just showing this to say I'm assuming 'field' to be > of type String > } > > rule "find value substring match" > when > $s : String ( ) > $t : Transaction( field.contains($s) ) > then > sendAlert("Transaction " + $t.getName() + "matches criteria: " + $s); > end > > ... > > session.insert(transaction); > for (int i = 0; i < listOfUserValueStrings.length; i++) { > session.insert(listOfUserValueStrings[i]; > } > > > > On Sat, Jan 5, 2013 at 1:29 PM, Jeremy Ary wrote: > >> If your matcher doesn't equate to a boolean value, I don't think that >> condition will evaluate as you suspect it will. Functions in your >> conditions isn't going to be as clean or easy as you suspect. Consider >> inserting the user-supplied values into your session and matching with a >> rule: >> >> ... >> public class Transaction { >> >> private String field; >> >> // ... getter and setter for field, as well as all your other >> methods in transaction, just showing this to say I'm assuming 'field' to >> be >> of type String >> } >> >> ... >> >> public class Value { >> >> private String value; >> >> public String getValue() { >> return value; >> } >> >> public void setValue(String value) { >> this.value = value; >> } >> } >> >> ... >> >> rule "find value substring match" >> when >> Value ( $v : value ) >> $t : Transaction( field.contains($v) ) >> then >> sendAlert("Transaction " + $t.getName() + "matches criteria: " + $v); >> end >> >> ... >> >> session.insert(transaction); >> for (int i = 0; i < listOfUserValues.length; i++) { >> session.insert(listOfUserValues[i]; >> } >> >> >> On Sat, Jan 5, 2013 at 12:29 PM, bdolbeare wrote: >> >>> Suppose we have a Transaction object with a String field. Users want to >>> create a rule through our application that says alert me whenever the >>> value >>> of that field contains a value in a list of values provided in the rule. >>> It's easy enough to write this type of rule and send an alert; however, >>> it >>> would be helpful to include the value from the list that matched. >>> >>> The only way I can think to do this type of thing is to create a >>> function >>> somewhere that checks if the field contains any of the values in the >>> user >>> list and if so return that value. Then call that function in the rule >>> condition and bind the result. Something like what follows: >>> >>> >>> public class ExternalMatcher >>> { >>> public static String contains(String field, String...list) >>> { >>> // return the first string that satisfies the contains logic or null >>> if >>> no >>> strings succeed >>> } >>> } >>> >>> rule "test" >>> when >>> Transaction( $matchedValue : ExternalMatcher.contains(field, "value1", >>> "value2", "value3") != null) >>> then >>> sendAlert("I found a transaction that matched your criteria because >>> field >>> foo equals: " + $matchedValue); >>> end >>> >>> >>> >>> >>> >>> -- >>> View this message in context: >>> http://drools.46999.n3.nabble.com/Finding-matching-values-in-composite-constraint-tp4021343p4021346.html >>> Sent from the Drools: User forum mailing
Re: [rules-users] Finding matching values in composite constraint
Reading it back over, I can simplify this a bit if we're solely dealing with strings... ... public class Transaction { private String field; // ... getter and setter for field, as well as all your other methods in transaction, just showing this to say I'm assuming 'field' to be of type String } rule "find value substring match" when $s : String ( ) $t : Transaction( field.contains($s) ) then sendAlert("Transaction " + $t.getName() + "matches criteria: " + $s); end ... session.insert(transaction); for (int i = 0; i < listOfUserValueStrings.length; i++) { session.insert(listOfUserValueStrings[i]; } On Sat, Jan 5, 2013 at 1:29 PM, Jeremy Ary wrote: > If your matcher doesn't equate to a boolean value, I don't think that > condition will evaluate as you suspect it will. Functions in your > conditions isn't going to be as clean or easy as you suspect. Consider > inserting the user-supplied values into your session and matching with a > rule: > > ... > public class Transaction { > > private String field; > > // ... getter and setter for field, as well as all your other > methods in transaction, just showing this to say I'm assuming 'field' to be > of type String > } > > ... > > public class Value { > > private String value; > > public String getValue() { > return value; > } > > public void setValue(String value) { > this.value = value; > } > } > > ... > > rule "find value substring match" > when > Value ( $v : value ) > $t : Transaction( field.contains($v) ) > then > sendAlert("Transaction " + $t.getName() + "matches criteria: " + $v); > end > > ... > > session.insert(transaction); > for (int i = 0; i < listOfUserValues.length; i++) { > session.insert(listOfUserValues[i]; > } > > > On Sat, Jan 5, 2013 at 12:29 PM, bdolbeare wrote: > >> Suppose we have a Transaction object with a String field. Users want to >> create a rule through our application that says alert me whenever the >> value >> of that field contains a value in a list of values provided in the rule. >> It's easy enough to write this type of rule and send an alert; however, it >> would be helpful to include the value from the list that matched. >> >> The only way I can think to do this type of thing is to create a function >> somewhere that checks if the field contains any of the values in the user >> list and if so return that value. Then call that function in the rule >> condition and bind the result. Something like what follows: >> >> >> public class ExternalMatcher >> { >> public static String contains(String field, String...list) >> { >> // return the first string that satisfies the contains logic or null if >> no >> strings succeed >> } >> } >> >> rule "test" >> when >> Transaction( $matchedValue : ExternalMatcher.contains(field, "value1", >> "value2", "value3") != null) >> then >> sendAlert("I found a transaction that matched your criteria because field >> foo equals: " + $matchedValue); >> end >> >> >> >> >> >> -- >> View this message in context: >> http://drools.46999.n3.nabble.com/Finding-matching-values-in-composite-constraint-tp4021343p4021346.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] Finding matching values in composite constraint
If your matcher doesn't equate to a boolean value, I don't think that condition will evaluate as you suspect it will. Functions in your conditions isn't going to be as clean or easy as you suspect. Consider inserting the user-supplied values into your session and matching with a rule: ... public class Transaction { private String field; // ... getter and setter for field, as well as all your other methods in transaction, just showing this to say I'm assuming 'field' to be of type String } ... public class Value { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } } ... rule "find value substring match" when Value ( $v : value ) $t : Transaction( field.contains($v) ) then sendAlert("Transaction " + $t.getName() + "matches criteria: " + $v); end ... session.insert(transaction); for (int i = 0; i < listOfUserValues.length; i++) { session.insert(listOfUserValues[i]; } On Sat, Jan 5, 2013 at 12:29 PM, bdolbeare wrote: > Suppose we have a Transaction object with a String field. Users want to > create a rule through our application that says alert me whenever the value > of that field contains a value in a list of values provided in the rule. > It's easy enough to write this type of rule and send an alert; however, it > would be helpful to include the value from the list that matched. > > The only way I can think to do this type of thing is to create a function > somewhere that checks if the field contains any of the values in the user > list and if so return that value. Then call that function in the rule > condition and bind the result. Something like what follows: > > > public class ExternalMatcher > { > public static String contains(String field, String...list) > { > // return the first string that satisfies the contains logic or null if > no > strings succeed > } > } > > rule "test" > when > Transaction( $matchedValue : ExternalMatcher.contains(field, "value1", > "value2", "value3") != null) > then > sendAlert("I found a transaction that matched your criteria because field > foo equals: " + $matchedValue); > end > > > > > > -- > View this message in context: > http://drools.46999.n3.nabble.com/Finding-matching-values-in-composite-constraint-tp4021343p4021346.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] Finding matching values in composite constraint
Suppose we have a Transaction object with a String field. Users want to create a rule through our application that says alert me whenever the value of that field contains a value in a list of values provided in the rule. It's easy enough to write this type of rule and send an alert; however, it would be helpful to include the value from the list that matched. The only way I can think to do this type of thing is to create a function somewhere that checks if the field contains any of the values in the user list and if so return that value. Then call that function in the rule condition and bind the result. Something like what follows: public class ExternalMatcher { public static String contains(String field, String...list) { // return the first string that satisfies the contains logic or null if no strings succeed } } rule "test" when Transaction( $matchedValue : ExternalMatcher.contains(field, "value1", "value2", "value3") != null) then sendAlert("I found a transaction that matched your criteria because field foo equals: " + $matchedValue); end -- View this message in context: http://drools.46999.n3.nabble.com/Finding-matching-values-in-composite-constraint-tp4021343p4021346.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] Finding matching values in composite constraint
I'm unaware of any mechanism that will allow you to identify what portions of the rete node triggered the activation directly as you've described. Ultimately, they resolve to booleans and having multiple conditions would further complicate your situation. However, I suspect that there's another approach to solving the issue at hand. Can you better describe the problem you're needing to solve that you'd want access to that information within the consequence? - jary On Sat, Jan 5, 2013 at 11:17 AM, bdolbeare wrote: > Is there a way to determine (in the rule consequence) which condition in a > composite constraint caused a rule to succeed? > > I am working on a system that allows users to create rules via a custom UI > and when one of their rules fires, I want to be able to create a message > that describes why their rule fired. In a real example, they might have a > list of a few hundred conditions in a composite constraint. > > An example rule with just two conditions in a composite constraint follows: > > rule "test rule" > when > MyObject( (myfield str[startsWith] "a" || myfield str[startsWith] "b") ) > then > System.out.prinltn(kcontext.getRule().getName() + " fired because myfield > started with ???"); > end > > Is this exposed somewhere in the variables like kcontext that are available > to each rule in their consequence? > > > > -- > View this message in context: > http://drools.46999.n3.nabble.com/Finding-matching-values-in-composite-constraint-tp4021343.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
[rules-users] Finding matching values in composite constraint
Is there a way to determine (in the rule consequence) which condition in a composite constraint caused a rule to succeed? I am working on a system that allows users to create rules via a custom UI and when one of their rules fires, I want to be able to create a message that describes why their rule fired. In a real example, they might have a list of a few hundred conditions in a composite constraint. An example rule with just two conditions in a composite constraint follows: rule "test rule" when MyObject( (myfield str[startsWith] "a" || myfield str[startsWith] "b") ) then System.out.prinltn(kcontext.getRule().getName() + " fired because myfield started with ???"); end Is this exposed somewhere in the variables like kcontext that are available to each rule in their consequence? -- View this message in context: http://drools.46999.n3.nabble.com/Finding-matching-values-in-composite-constraint-tp4021343.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