I want to insert a list of objects in the then part dynamically when this rule is included for run.
rule "insert adresses"
when
$person:Person(state=="DC")
then
//insert all address of this person, person.getAddresses() return a set of Address
2 possible ways:
rule "insert adresses"
when
$person: Person(state=="DC")
$a: Address() from $person.getAddresses()
then
insert($a);
end
and
rule "insert adresses"
when
$person: Person(state=="DC")
then
for (Address a : $person.getAddresses()){
insert(a);
}
end
Both rules have the same result. Maybe option number one is better if you want to add some filter to the addresses you want to insert.
Hope it helps,
In fact I think that there are some differences. In option 1 there will be one activation and fire per Address. In option 2 you will have just one activation and fire per person.
It is true that with the second option you cannot filter the Addresses in a nice way, but you will definitely reduce the firings. It all depends on what do you want to do with the addresses and if you care about the firings or not.
Related
I have the below use case.
Let's say I have user, order details in the same collection.
Id is user_id|order_id
I have the below informations in single document.
user_detail: {
name, age, email, address
}
Assume single email, single address, single phone number field.
Then order detail which contains order id, order items, etc.
Order details contains indices also.
Note: My use case is something different I am trying to map it.
Approach 1:
Replace the order details. Replace that order wherever it is present.
Approach2:
Have a order collection, compare the changes on the order, update the changed fields where and all this order is present for that customer.
Here, order detail could be present on multiple users. Kindly assume to map my use case.
I implemented approach 2. It seems time consuming, non-scalable. I wonder which one is better or any new approaches? My concern is more about the data in the index.
Any suggestions?
I'm making a conditional formula in Crystal Reports for the record selection. The value of {IDENTITY_ADDRESS.ADDRESS_TYPE} can be either 1 (Present Street Address) or 3 (Present Mailing Address).
There will always be a Street Address (1) but I would prefer to use the Mailing Address (3) if one exists. How can I accomplish this?
You'll probably want to write a custom SQL statement inside Crystal to handle this. Since custom-tooled SQL tables evaluate before the report is even reached, it will do the record selection for you.
I can't see your tables so you'll have to write the logic yourself. But the gist is that you'll want to return a new field, let's call it PreferredAddress which will be a varChar that will:
Check to see if a Present Mailing Address (3) is on file for this record
If yes, return the Present Mailing Address (3) as PreferredAddress
If no, return the Present Street Address (1) as PreferredAddress
if {IDENTITY_ADDRESS.ADDRESS_TYPE} = Present Mailing Address
then true,
else
{IDENTITY_ADDRESS.ADDRESS_TYPE} = Present Street Address
rule "one"
activation-group "Harris"
salience 10
when
$p : Person(age < 10);
then
$p.setDiscount(0.1);
end
rule "two"
activation-group "Harris"
salience 10
when
$p : Person(age > 10);
then
$p.setDiscount(0.2);
end
When I insert some Persons to working memory through KSession.insert(Object), only the first Person is evaluated, the other persons just ignored. My understanding about Drools activation-group is that if I have X number of rules that belong to the same activation-group with various salience values that each
Person will be processed by the rules and the one with the highest
salience will be fired and the rest will be ignored. Once that's
complete the next Person will come through and repeat the process. What
I'm experiencing is that the first Person to trigger any rule in that
activation-group will disable the entire activation group and no further
Persons will be processed.
Any suggestion?
"Only one rule within an activation group will fire, i.e., the first one to fire cancels any existing activations of other rules within the same group." This is pretty explicit.
Don't use an activation group if you want to do the same thing for many Person facts.
(a) Insert just one, fire all rules - repeat.
(b) Insert many persons, fire all rules but retract a Person fact in each consequence.
Salience is almost always bad. Use logic (constraints) for fine-grained control of the rule firing order.
activation-group will not work in your case. Insert and fireAlleules one by one shockingly that will work because it will fire up the rules considering the new updates in KnowledgeBase.(Not Recommended).
But i would suggest you to write up the unique rules to avoid activation-group. You can also try extending rules for more constructive.
I am using the native rule engine of webMethods (wm Business rule) to create complex rule. I need to create a decision table that depends on the result of another decision table. As shown in the graphic below,
I finally find out how to do it.
The idea is to put both decision tables into the same rule set. Then running the rule set by providing var1, var2, param1 and param2
The rule engine is going to infer the result for the first decision table into the second one.
NB. the name of the result of the first table has to be the same in the second table.
I read the rule file and add them into my knowledgeBase then I want to fire a particular rule in that knowledgeBase. Is this task possible in current drools version?
If you have a rule base where rules should be made active dynamically according to some criterion you have several choices.
Agenda filter. You say you don't want this, but why?
Put the alternative rules into agenda groups. Select the agenda group "group_3" prior to inserting the fact by a call to
kieSession.getAgenda().getAgendaGroup( "group_3" ).setFocus();
Write your rules to include a "selection" fact, e.g.
rule rule_3
when
Select( rule == "rule_3" )
Person( ... )
then ... end
The Select fact can be inserted along with the data fact but must be retracted after firing the rule.