I don't know your data model, but I believe, what you may be looking for is;
CONDITION:
$pt: Patient ( )
$test : LabTest( ) from $pt.labTests
not (exists (LabTest (testId == $test.testId)))
CONSEQUENCE
Insert($test);
If I am recalling this correctly, line2 does not inject anything into working memory yet,
and the only reference in memory to the collection of tests for the patent is $test.
Whereas Line 3 uses the Rete indexed items that were inserted into working memory, so what
you are effectively doing, is blocking the fact from being inserted twice, because one it
is inserted, it is indexed, and associated with the rules where it is uses, and since this
rule states it must not exist, this rule cannot fire again, since it can only be activated
when there is no matching labTest.
However, the test should not be inserted more than once, because it should only fire for
changes, not the whole list every time. To trigger a change on the original version of
the rule, you would have to change the Patient record to trigger a reactivation of the
rule.
In this modified version of the rule, any change to LabTest or Patient would trigger a
reactivation of the rule, so the original version may be the better rule, since it
involves less work to evaluate the activation triggers (only slightly, but less is less).
-----Original Message-----
From: rules-users-bounces(a)lists.jboss.org [mailto:rules-users-bounces@lists.jboss.org] On
Behalf Of Pedro Loaiza
Sent: Monday, April 23, 2012 4:59 AM
To: Rules Users List
Cc: rules-users(a)lists.jboss.org
Subject: Re: [rules-users] Performace Issues drools
I want implement this. How would you control the insertion rule in order to avoid having
it insert duplicates or re-fire?
Thanks
On Apr 19, 2012, at 10:56 AM, "Welsh, Armand" <AWelsh(a)statestreet.com>
wrote:
This may no longer be the case, but my understanding is that when you
use from to query data from a member list of another object in working memory, that those
members are not indexed by Rete.
I think every time the rule evaluates, it has to iterate through the entire member list
(collection) to find the matching facts that are extracted for additional evaluation.
With that said, if you have one rule that extracts the facts, and inserts them into
working memory, they will be indexed and now many operations on the fact type will be
pre-computed at the time of insert, improving performance dramatically. I don't know
if this makes sense, but consider the following:
CONDITION:
$pt: Patient ( )
LabTest( ) from $pt.labTests
$numTests: Number ( ) from accumulate ( LabTest($type: type == "lab"),
count($type) )
Drools first collects all the Patient facts and for each Patient it extracts the
collections of tests. Now the collection of patients are already known by Rete, so this
has been pre-computed at time of fact insert.
Next, for each Patient fact, drools extracts the collection of LabTests performed. These
are not indexed by Rete to they are not actually in working memory. Each time this rule
is evaluated, the collection of LabTests must be generated.
Next the accumulate evaluates the LabTest facts to find those that have a getType() ==
"lab". Since the facts do not exist in working memory, accumulate iterates all
the LabTest fact and extracts just the ones where getType == "lab". If the rule
file 10 times, that's 10 iterations of the collection.
If you break this into two rules:
CONDITION:
$pt: Patient ( )
$test : LabTest( ) from $pt.labTests
CONSEQUENCE
Insert($test);
CONDITION:
$numTests: Number ( ) from accumulate ( LabTest($type: type == "lab"),
count($type) )
In this scenario, Drools only extracts the LabTest facts once, and inserts them in
working memory, so that when the 2nd rule is evaluated, it is already known which LabTest
facts are in memory that exist, and the iteration only happened once, at insert time,
instead at every rule evaluation.
My understanding may be obsolete, and inaccurate as it applies to Drools 5.4, but this is
the type of coding changes I have made in the past to improve performance. The key is
knowing how to control the insertion rule, so it does not insert duplicates, or refire
unexpectedly.
Care must be taken to ensure you are properly binding your facts when you do this
though... But the most speed benefit in drools comes from using the rete engine to avoid
multiple iterations of the same collection...
-----Original Message-----
From: rules-users-bounces(a)lists.jboss.org [mailto:rules-users-bounces@lists.jboss.org] On
Behalf Of sanal
Sent: Tuesday, April 17, 2012 4:27 AM
To: rules-users(a)lists.jboss.org
Subject: Re: [rules-users] Performace Issues drools
Hi,
Still Iam facing some issues with the accumulte.Please see the below
senario.I am trying to explain with the below example.
Suppose Glucose is a OrderedComponent which is under Labgroup.
PackageComponent(Rule)
------------------------------
LABGroup (ComponentKey=100) qtyLimit(2)
OrderedComponent
-------------------------------
Order1 Glucose (ComponentKey=101) Ordered qty (1)
ParentKey(100), ParentKey(4)
Order2 Glucose (ComponentKey=101) Ordered qty (1)
ParentKey(100) ,ParentKey(4)
Order3 Glucose (ComponentKey=101) Ordered qty (1)
ParentKey(100), ParentKey(4)
Rule execution flow which i require.
1) I need to check any rule exist for Orderedcomponent.If exist Execute the
Rule.
In this case no rule exist for glucose.
2) If no rule is found for the Orderedcomponent.I need to Check if any rule
exist for its parent(group).
I am trying to achive this by changing the component key. The component
key is changed to that of
the parent and the rules are executed once again.This process is
contiuned until any rules exist for the group
or root parent is reached(tree format).
1st Issue
Here parent of glucose is Lab. And Lab has got rule.So the Parent rule
of lab should get executed.
In this senario only 2 glucose orders should go under package. 3rd one
should not go under package.
With my existing Drl all the 3 are going inside the package.How can i
correct this?
2nd Issue
While accumulating with lab group,all ordered items whose parent group is
lab should be summed up.
The salience is used in such a manner because i need to execute the rules
for the services first
and later the rules for its parents group.
Please find the modified drl as per your suggestion.
package com.his.billing.domain;
import com.his.clinical.domain.PackageDefinition;
import com.his.clinical.domain.PackageComponent;
import com.his.billing.domain.OrderedComponent;
import com.his.billing.domain.AccumulatedComponent;
/*#From row number: 12*/
rule "Check whether is orderedComponent is excluded"
salience 7
when
$objOrderedComponents:AccumulatedComponent()
$orderedComponent:OrderedComponent($id1:componentKey,$orderTariffClassType:tariffClassType,$orderTariffClassId:tariffClassValue)
and
$pkgComps:PackageComponent(componentKey==$id1,isExcluded==true,(tariffClassTypeValue==null
|| tariffClassTypeValue=="" || (tariffClassTypeValue!=null &&
tariffClassTypeValue == $orderTariffClassType)),(tariffClassValue==null ||
(tariffClassValue!=null &&
tariffClassValue==$orderTariffClassId)),isPackageComponent==true,isActive==true)
then
$orderedComponent.setIsExluded(true);
$orderedComponent.setIsPackageComponent(true);
end
/*#From row number: 21*/
rule "Check whether is orderedComponent quantity limit exceeded"
salience 6
when
$objOrderedComponents:AccumulatedComponent()
$packageDefinition:PackageDefinition($packageId:packageId)
$orderedComponent:OrderedComponent($id1:componentKey,$amount:componentAmt,$qty:componentQty,$orderTariffClassType:tariffClassType,$orderTariffClassId:tariffClassValue)
and
$accumulatedQty:Number()
from accumulate (
$accQtyComponent:OrderedComponent(packageChargeRecordId==$packageId, $AccQty
: componentQty) from
$objOrderedComponents.getOrderedComponentList(),sum($AccQty ) ) and
$pkgComps:PackageComponent(componentKey==$id1,(quantityLmt == 0 ||
quantityLmt != null || quantityLmt
<($qty+$accumulatedQty.intValue())),isPackageComponent==true,isActive==true,(tariffClassTypeValue==null
|| tariffClassTypeValue=="" || (tariffClassTypeValue!=null &&
tariffClassTypeValue == $orderTariffClassType)),(tariffClassValue==null ||
(tariffClassValue!=null && tariffClassValue==$orderTariffClassId)))
then
$orderedComponent.setIsQtyExceeded(true);
$orderedComponent.setIsPackageComponent(true);
end
/*#From row number: 21*/
rule "Check whether is orderedComponent Amount limit exceeded"
salience 5
when
$objOrderedComponents:AccumulatedComponent()
$packageDefinition:PackageDefinition($packageId:packageId)
$orderedComponent:OrderedComponent($id1:componentKey,$amount:componentAmt,$qty:componentQty,$orderTariffClassType:tariffClassType,$orderTariffClassId:tariffClassValue)
and
$accumulatedAmount:Number()
from accumulate (
$accAmtComponent:OrderedComponent(packageChargeRecordId==$packageId,$accAmount:componentAmt)
from $objOrderedComponents.getOrderedComponentList(),sum($accAmount ) ) and
$pkgComps:PackageComponent(componentKey==$id1,( amountLmt == 0 ||
amountLmt == null || amountLmt
<($amount+$accumulatedAmount.intValue())),isPackageComponent==true,isActive==true,(tariffClassTypeValue==null
|| tariffClassTypeValue=="" || (tariffClassTypeValue!=null &&
tariffClassTypeValue == $orderTariffClassType)),(tariffClassValue==null ||
(tariffClassValue!=null && tariffClassValue==$orderTariffClassId)))
then
$orderedComponent.setIsAmtExceeded(true);
$orderedComponent.setIsPackageComponent(true);
end
/*#From row number: 22*/
rule "Check whether is orderedComponent is exempted"
salience 4
when
$objOrderedComponents:AccumulatedComponent()
$orderedComponent:OrderedComponent($id1:componentKey)
$pkgComps:PackageComponent(componentKey==$id1,isPackageComponent==true,exemption==true,isActive==true)
then
$orderedComponent.setExemption(true);
$orderedComponent.setIsPackageComponent(true);
end
/*#From row number: 21*/
rule "Check whether orderedComponent satisfy all rules.Then assign package
id"
salience 3
when
$objOrderedComponents:AccumulatedComponent()
$packageDefinition:PackageDefinition($packageId:packageId)
$orderedComponent:OrderedComponent($id1:componentKey,packageChargeRecordId!=$packageId,$amount:componentAmt,$qty:componentQty,$orderTariffClassType:tariffClassType,$orderTariffClassId:tariffClassValue)
and
$accumulatedAmount:Number()
from accumulate (
$accAmtComponent:OrderedComponent(packageChargeRecordId==$packageId,$accAmount:componentAmt)
from $objOrderedComponents.getOrderedComponentList(),sum($accAmount ) ) and
$accumulatedQty:Number()
from accumulate (
$accQtyComponent:OrderedComponent(packageChargeRecordId==$packageId, $AccQty
: componentQty) from
$objOrderedComponents.getOrderedComponentList(),sum($AccQty ) ) and
$pkgComps:PackageComponent(componentKey==$id1,isExcluded==false,(amountLmt
== 0 || amountLmt == null || amountLmt
> =($amount+$accumulatedAmount.intValue())),( quantityLmt ==0 || quantityLmt
==null || quantityLmt
>
=($qty+$accumulatedQty.intValue())),isPackageComponent==true,isActive==true,(tariffClassTypeValue==null
|| tariffClassTypeValue=="" || (tariffClassTypeValue!=null &&
tariffClassTypeValue == $orderTariffClassType)),(tariffClassValue==null ||
(tariffClassValue!=null && tariffClassValue==$orderTariffClassId))) from
$packageDefinition.getPackageComponentList()
then
$orderedComponent.setIsComponentApplicable(true);
$orderedComponent.setPackageChargeRecordId($packageId);
$orderedComponent.setIsPackageComponent(true);
modify($orderedComponent){};
modify($objOrderedComponents){};
end
/*#From row number: 22*/
rule "If no rule exist for orderedComponent Check whether orderedComponent
is a pharmacy item then assign its generic naame and then apply the rules"
salience 2
when
$objOrderedComponents:AccumulatedComponent()
$orderedComponent:OrderedComponent($id1:componentKey,isPackageComponent==false,componentType=="1052374",haveReachedRootNode==false)
then
$orderedComponent.setGenericComponentKey();
modify($orderedComponent){};
modify($objOrderedComponents){};
end
/*#From row number: 22*/
rule "If no rule exist for orderedComponent Check whether rule exist for
its parent group"
salience 1
when
$objOrderedComponents:AccumulatedComponent()
$orderedComponent:OrderedComponent($id1:componentKey,isPackageComponent==false,haveReachedRootNode==false)
then
$orderedComponent.setGroupComponentKey();
modify($orderedComponent){};
modify($objOrderedComponents){};
end
Regards
Sanal.P
--
View this message in context:
http://drools.46999.n3.nabble.com/Performace-Issues-drools-tp3902270p3916...
Sent from the Drools: User forum mailing list archive at
Nabble.com.
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org