Oracle® Database Rules Manager and Expression Filter Developer's Guide 11g Release 2 (11.2) Part Number E14919-04 |
|
|
PDF · Mobi · ePub |
Rules Manager rule conditions use the SQL WHERE
clause format and the attributes of the event structure to define the rule condition. For the travel services example, you express the rule condition using the attributes: Airline
, ToCity
, Return
, and Depart
. Rule conditions you define on primitive event structures correspond directly to the SQL WHERE
clause format:
<condition> Airline = 'Abcair' and ToCity = 'Orlando' and Return - Depart >=7 </condition>
Note that you embed all rule conditions within XML <condition>
tags. Rules Manager provides additional XML tags to support incremental evaluation of rule conditions for composite events (which are composed of two or more primitive events).
You may recall that evaluating a condition based on a primitive event is atomic, implying that the values for all attributes of that event structure are available atomically. Thus, when you define a rule condition on a primitive event, it evaluates to true or false instantaneously. In contrast, when you define a rule condition on a composite event, it may have intermediate states, depending on the subset of the primitive events that are available. For example, when you define a rule on a composite event constructed from three primitive events, you can define it to fire if any two of the three primitive event conditions are true.
To support rule conditions on composite events, you can use additional XML tags within the <condition>
tags. These tags extend the basic WHERE
clause functionality, supporting joins between composite events, and incremental evaluation of the primitive event instances that comprise the composite event structure.
For example, the conditional expression (Flt.Airline = 'Abcair' and Flt.ToCity = 'Orlando' and Flt.CustId = Car.CustId and Car.CarType = 'Luxury'
) in the travel services rule has three parts, as follows:
Predicates defined on the primitive event AddFlight (Flt.Airline = 'Abcair' and Flt.ToCity = 'Orlando'
)
A predicate defined on the primitive event AddRentalCar (Car.CarType = 'Luxury'
)
A join predicate between the two primitive events (Flt.CustId = Car.CustId
)
Rules Manager provides XML tags to identify various parts of a complex conditional expression and support additional semantics. For example, you can represent the previous rule condition using XML tags as followsFoot 1 :
<condition> <and join="Flt.CustId = Car.CustId"> <object name="Flt"> Airline='Abcair' and ToCity='Orlando' </object> <object name="Car"> CarType = 'Luxury' </object> </and> </condition>
In this representation, the <object>
elements capture the predicates specified for individual primitive events and one join attribute of the <and>
element captures the join predicate behavior between two primitive events. You can insert the rule condition in this format into the rlm$rulecond
column of the corresponding rule class table. Rules Manager provides XML tags to support more complex rule constructs. Figure 5-1 and Table 5-1 summarizes these tags and Section 5.2 through Section 5.5 describe these tags in more detail.
The previous example illustrates the combination of and with a join, which evaluates to true when all the primitive event conditions evaluated to true with the corresponding events, which also satisfy the rule's join condition. Other constructs, such as any, enable complex conditions to be specified that evaluate to true if a subset of the primitive event conditions are true.
The most common join predicate used to form composite events is an equality predicate, as is the case with SQL queries that join multiple tables. Usually, one or more attributes from each primitive event are compared with one or more attributes from the other events for equality. Rules Manager uses a convenient syntax to specify the equality join predicates in the rule conditions and also provides a mechanism to enforce this join predicate for all the rules in a rule class (Section 3.5).
The following are examples of commonly used rule constructs defined on composite events.
Count based subsets of primitive events. Specify by using the any operator.
The operator any evaluates to true if any of the primitive event conditions evaluate to true.
The operator any 2 evaluates to true if any 2 or more of the primitive event conditions evaluate to true.
In general, the any operator is parameterized with a count argument, which evaluates to true if any count of the primitive event conditions evaluate to true.
Sequenced subsets of primitive events. Specify these in a number of ways:
Use a Join with a time constraint. Use the time constraint to impose a partial order over the event instances.
Use combinations of and with a sequence tag.
The sequence tag requires a specific ordering of primitive events.
Use combinations of any count with a sequence tag.
Detecting if one primitive event does not occur within a certain time interval of another primitive event. Specify this using the by option of the not or notany tag:
Use the not by tag with a timestamp parameter to detect the non-occurrence of a primitive event within a specific time interval.
Use the notany by tag in a similar fashion.
Figure 5-1 describes a hierarchical view of the supported XML tag elements and their attributes for the rule condition XML schema definition that is described in detail in the Rule Condition section in Appendix F. Table 5-1 shows a relational view of the same supported XML tag extensions showing the XPath and some notes about the elements and attributes.
Figure 5-1 Hierarchical View of the XML Tag Extensions
Table 5-1 Relational View of the XML Tag Extensions
XML Tag | Type | Parent | XPath | Number of Occurrences Allowed within Its Parent | Notes |
---|---|---|---|---|---|
|
Element |
None |
|
--- |
Denotes a conditional expression |
|
Element |
|
|
One |
Combines predicates |
|
Element |
|
|
One |
A substitute for "or"; true if any condition is met |
|
Element |
|
|
One, as last child element |
Logical negation |
|
Element |
|
|
One, as last child element |
Logical negation; detects non-occurrence |
|
Element |
|
|
One Two or more objects Two or more objects One object Two or more objects |
Primitive event |
|
Element |
|
|
One Two or more in combination with object |
Collection event |
|
Attribute |
|
|
One One One One |
Joins predicates |
|
Attribute |
|
|
One One |
Specifies an ordered sequence Specifies any ordered sequence |
|
Attribute |
|
|
One One |
Joins predicates |
|
Attribute |
|
|
One One |
Any n semantics Any n semantics |
|
Attribute |
|
|
One One |
Deadline for non-occurrence Deadline for non-occurrence |
|
Attribute |
|
|
One |
Object name |
|
|
Collection name |
|||
|
Attribute |
|
|
One |
Reference to a shared condition |
|
Attribute |
|
|
One |
Group by specification for the collection |
|
Attribute Attribute |
|
|
One One |
Having clause for the collection Having clause joining multiple collections |
|
Attribute |
|
|
One |
Additional aggregate function to compute for the collection |
|
Attribute |
|
|
One |
Moving window spec for collection |
|
Attribute |
|
|
One |
Moving window spec for collection |
The rules you define for a composite event (consisting of two or more primitive events) may specify a condition on the order in which the primitive events should occur. This is called sequencing and it can be partial on a subset of primitive events, or it can be complete based on all the primitive events. Sequencing in rule applications uses the implicit timestamp attribute (rlm$crtTime
) that is included in each primitive event participating in a composite event.
Rules Manager uses the event creation times in the primitive events to enforce and detect sequencing in rule applications. For example, consider the rule in the travel services application. You can specify an additional predicate to offer the promotion only if the AddRentalCar
event is generated after the AddFlight
event. You can extend the rule condition to include this sequencing predicate, as follows:
<condition>
<and join="Flt.CustId = Car.CustId" sequence="yes">
<object name="Flt"> Airline='Abcair' and ToCity='Orlando' </object>
<object name="Car"> CarType = 'Luxury' </object>
</and>
</condition>
The sequence attribute in the preceding example ensures that the rule condition evaluates to true only if the matching primitive events occur in the order in which they are specified within the <and>
element. You can replace the sequence attribute with a join predicate on the corresponding event creation times, shown as follows:
<condition>
<and join="Flt.CustId = Car.CustId and Car.rlm$CrtTime >= Flt.rlm$CrtTime">
<object name="Flt"> Airline='Abcair' and ToCity='Orlando' </object>
<object name="Car""> CarType = 'Luxury' </object>
</and>
</condition>
You can use sequencing to detect partial ordering among primitive events (for example, using a join predicate on only two primitive events when there are three of them in the composite event). You can also use the rlm$CrtTime
attribute in the primitive event type to apply additional time constrains in the rule conditions. For example, the travel services rule may be valid only when the car reservations is made within 24 hours of making the flight reservation. The boldfaced text of the following example indicates where the value 1
means one day. See Oracle Database Advanced Application Developer's Guide for more information about performing date or timestamp arithmetic.
<condition>
<and join="Flt.CustId = Car.CustId and
Flt.rlm$CrtTime >= (Car.rlm$CrtTime - 1)"
sequence="Yes">
<object name="Flt"> Airline='Abcair' and ToCity='Orlando' </object>
<object name="Car"> CarType = 'Luxury' </object>
</and>
</condition>
Optionally, the call to the DBMS_RLMGR.PROCESS_RULES
procedure may pass an event with a specific event creation time. Within a primitive event, Rules Manager treats the rlm$CrtTime
attribute as any other attribute in the event structure. However, when you do not specify a value for this attribute, it is assigned a default value of SYSTIMESTAMP
(in the database). If an application is sensitive to the difference between the times at which the events are detected (in the application layer) and the times at which they are added to Rules Manager, it may choose to set the values for event creation times and add fully specified events to the rule class.
Typically, you use rules with negation in their conditions to raise exceptions in business processes. For example, a rule using negation could be "If an order is placed by a Gold customer and the items are not shipped within 24 hours of the order placement, alert the representative". In this case, you define the rule for a composite event consisting of two primitive events PlaceOrder
and ShipOrder
and the type created for the composite event structure is shown as follows:
CREATE or REPLACE TYPE OrderTrack AS OBJECT ( order PlaceOrder, -- primitive event type -- ship ShipOrder); -- primitive event type --
For a composite event, a rule defined with negation evaluates to true when one of the primitive events does not happen within a time delay of the other. So, negation always accompanies a time delay that is relative to the other primitive event or events in the composite event. For example, you can express the rule condition for the order tracking rule as shown in the following example. The boldfaced text, "sysdate +1", means by the end of the next day because the SQL datetime function SYSDATE
returns the current date and time of the operating system on which the database resides (taking into account the time zone of the database server's operating system that was in effect when the database was started).
<condition>
<and equal="order.orderId, ship.orderId">
<object name="order"> Type = 'Gold' </object>
<not by="sysdate+1">
<object name="ship"/> -- empty elem: no conditions on the primitive event --
</not>
</and>
</condition>
The <not>
XML element in the rule condition has the following semantics:
There can be only one <not>
element in a rule condition.
The <not>
element can only appear within an <and>
element (as a conjunction to other primitive events) and it should be the last element within the <and>
element.
The <not>
element is activated only when all the other primitive events in the composite events are detected.
The <not>
element can contain only one <object> element that represents a primitive event.
Use the <notany>
element in place of the <not>
element to support a notion of disjunction within the negation rule.
At the time of activation, Rules Manager executes the by
attribute of the <not>
element to compute the deadline for the primitive events in the <not>
element. You can express the value for the by
attribute using the (database) SYSTIMESTAMP
(to be set to the time of activation) or any date attribute in the other primitive events (including the event creation time attributes discussed in Section 5.2), or both. The SQL datetime function SYSTIMESTAMP
returns the system date including fractional seconds and time zone of the system on which the database resides. So, you can also express the rule condition in the preceding example as follows:
<condition>
<and equal="order.orderId, ship.orderId">
<object name="order"> Type = 'Gold' </object>
<not by="order.rlm$CrtTime+1">
<object name="ship"/>
</not>
</and>
</condition>
Another variant of the preceding rule is one that uses a user-supplied date in the deadline computation. For example, a ShipBy
attribute in the PlaceOrder
event can hold the time by which you expect the shipment and the deadline can be computed using this attribute, such as shown here:
<condition>
<and equal="order.orderId, ship.orderId">
<object name="order"> Type = 'Gold' </object>
<not by="order.ShipBy-1">
<object name="ship"/>
</not>
</and>
</condition>
Rules with negation involving a deadline other than SYSTIMESTAMP
are not allowed in a rule class with the AUTOCOMMIT
property turned off (see Section 3.6). This also includes the rule classes configured for DMLEVENTS
(see Section 3.7).
You can use rules involving negation constructs to raise alerts (in corresponding rule actions) when a set of primitive events are generated out of order. In applications such as Workflow, rules are often used to enforce sequencing among various business events. The action of such rules is to raise an exception (alert an agent) when the events are detected out of order. You can use a <not>
element without a hard deadline (no by
attribute) to define such rules.
Consider a composite event with three primitive events: PlaceOrder
, PaymentReceived
, and ShipOrder
. You can use a rule to alert an agent (action) if the ShipOrder
event is generated before the PaymentReceived
event is detected. (Note that there are alternate ways to model this application in a Workflow system, but this approach is used to explain the negation concept). For this example, you can represent the composite event structure and the rule condition as follows:
CREATE or REPLACE TYPE OrderTrack AS OBJECT ( order PlaceOrder, -- primitive event type –- pay PaymentReceived, -- primitive event type -- ship ShipOrder); -- primitive event type -- <condition> <and equal="order.OrderId, pay.OrderId, ship.OrderId"> <object name="order"/> -- no conditions on the primitive events -- <object name="ship"/> <not> <object name="pay"/> </not> </and> </condition>
The previous example uses a <not>
element with no deadline specification (by
attribute) and thus this value defaults to SYSTIMESTAMP
(the time at which all other primitive events in the rule condition are detected). You can use the sequence="yes" (Section 5.2) property, such as shown in the following example, to ensure ordering among the detected events.
<condition> <and equal="order.OrderId, pay.OrderId, ship.OrderId" sequence="yes"> <object name="order"/> -- no conditions on the primitive events -- <object name="ship"/> <not> <object name="pay"/> </not> </and> </condition>
In the previous rule condition, you determine the deadline for the PaymentReceived
event by the occurrence of the ShipOrder
event, which follows the corresponding PlaceOrder
event. In effect, if the ShipOrder
event is detected before the PaymentReceived
event for a particular order, the rule application executes the action associated with the preceding rule condition.
You can often use the negation construct to detect the non-occurrence of two or more primitive events. For example, a rule such as "If an order is placed by a Gold customer and the items are not shipped within 24 hours of the order placement or if the order is not cancelled, alert the representative" uses negation on the two events, ShipOrder
and CancelOrder
. You can express such rule conditions using a <notany>
element in the place of the <not>
element as shown in the following example:
<condition> <and equal="order.orderId, ship.orderId, cancel.orderId"> <object name="order"> Type = 'Gold' </object> <notany count=1 by="order.rlm$CrtTime+1"> <object name="ship"/> <object name="cancel"/> -- assuming a CancelOrder event -- </notany> </and> </condition>
The primitive events appearing within the <not>
or <notany>
element should not be referenced in the join
attribute specification of the <and>
element. However, you can use primitive events within the EQUAL
property specifications. If there is a need to specify a join condition (other than those already captured by the EQUAL
property specifications), you can use the join
attribute for the <not>
element. The conditional expression specified for this join
attribute can reference all the primitive events that appear in the rule condition, including those appearing within the <not>
element, such as shown in the following example:
<condition>
<and equal="order.orderId, ship.orderId">
<object name="order"> Type = 'Gold' </object>
<not by="order.rlm$CrtTime+1"
join="order.Address_zipcode = ship.Address_zipcode">
<object name="ship"/>
</not>
</and>
</condition>
The rule condition with a negation is considered true only if the join condition in the <and>
element evaluates to true and the join condition in the not condition evaluates to false (or there is no event that matches this criteria within specified deadline).
In some applications, the primitive events that constitute a composite event can be the same structure. For example, AddItem
could be a primitive event that is generated when a customer adds an item to his shopping cart. You can define rules to monitor multiple items added to the shopping cart and suggest new items based on the past customer experiences (association rules generated by a data mining tools).
Consider an electronics Web store that sells accessories for camcorders. A typical rule in their application could be "If a customer adds a camcorder lens worth more than $100, a lens filter, and a IR light to the shopping cart, suggest a tripod to him". This rule consists of three simple conditions to be checked on every AddItem
event generated in the system, such as shown in the following example:
Accessory = 'Lens' and Price > 100 Accessory = 'Lens Filter' Accessory = 'IR Light'
To support the application described previously, you model the composite event structure as an object type with multiple embedded types of the same primitive event type (AddItem
) as shown in the example that follows. If required, the same composite event structure may also include other primitive event types.
CREATE or REPLACE TYPE AddItem AS OBJECT ( Accessory VARCHAR(30), Make VARCHAR(20), Price NUMBER); CREATE or REPLACE TYPE CrossSellEvent AS OBJECT ( Item1 AddItem, Item2 AddItem, Item3 AddItem, Item4 AddItem, Item5 AddItem);
The preceding composite event is created to accommodate rules that are monitoring at most five primitive events in the shopping cart. (Note that the shopping cart may still contain more than 5 items.) In this rule application, you can configure the events for SESSION
duration (see Section 3.3) such that only the primitive events generated within a user session are considered for rule matches. Using the composite event rule condition syntax, you can express the preceding condition as follows:
<condition> <and> <object name="Item1"> Accessory = 'Lens' and Price > 100 </object> <object name="Item2"> Accessory = 'Lens Filter' </object> <object name="Item3"> Accessory = 'IR Light' </object> </and> </condition>
Note that you use the element names Item1
, Item2
, and Item3
to assign the matching events to appropriate attributes of the CrossSellEvent
instance. Also, this assignment allows (join) predicates across primitive events in a rule condition as follows:
<condition>
<and join="Item1.Price+Item2.Price+Item3.Price > 300">
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</and>
</condition>
The maximum number of primitive events allowed in a composite event limits the total number of primitive events you can consider in a rule condition with set semantics. Also, following standard SQL semantics, you cannot use aggregate operators in the join conditions to relate multiple events. For rule-based applications involving aggregate operators over a finite, but potentially large number of primitive events, you should configure the rule class for collection events and the rule conditions should specify predicates on these collections.
The examples discussed so far use rules that match all the primitive events specified in a rule condition. You achieve this with the use of an <and>
element as the parent of all the primitive event conditions. Some rule applications require rules that could match a subset of primitive events specified in the rule condition. For example, consider a composite event CE1
consisting of three primitive events PE1
, PE2
, and PE3
. Now, a rule condition you define for the composite event may need to match only one of the three primitive events. For this example, you represent the composite event structure and the rule condition as follows:
-- Composite event structure -- CREATE or REPLACE TYPE CE1 AS OBJECT ( pe1Inst PE1, pe2Inst PE2, pe3Inst PE3); -- Sample Rule condition -- <condition> <any> <object name="pe1Inst"/> <object name="pe2Inst"/> <object name="pe3Inst"/> </any> </condition>
When the rule condition should match any two of the three primitive events, use the count
attribute of the <any>
element, as shown in the example that follows. By default, the count
attribute has a value of 1, which is equivalent to a disjunction (OR) of all the primitive events specified within the <any>
element.
<condition> <any count=2> <object name="pe1Inst"/> <object name="pe2Inst"/> <object name="pe3Inst"/> </any> </condition>
The Any n semantics in the rule conditions are very common in applications using set semantics. The rule considered in the cross-selling application of Section 5.4 can be extended to suggest the tripod to the customer if the shopping cart has any two of the three items specified. You can represent the condition for this rule using the Any n syntax as follows:
<condition>
<any count=2>
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</any>
</condition>
In a rule condition, some of the primitive events specified within an <any>
list may be mandatory for the condition to evaluate to true. For example, in the preceding rule condition, the Lens (Item1) may be mandatory and it should always count for one item in two items matched with the <any count=2>
specification. You can represent this new rule condition using the join attribute of the <any>
element as follows:
<condition>
<any count=2 join="Item1 IS NOT NULL">
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</any>
</condition>
Within an <any>
list, often there is a need to correlate the primitive events that occur. For example, you can extend the preceding rule to suggest the tripod to the customer only if the Make
attribute of the two items matched is same. When using an <and>
element (to match all three items), you can pose this as a join
predicate on the Make
attribute of each primitive event, such as shown in the following example:
<condition>
<and join="Item1.Make=Item2.Make and Item2.Make=Item3.Make">
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</any>
</condition>
However, you cannot use similar join predicates to correlate primitive events in an <any>
list because the missing primitive events (the one left out in 2 out of 3) are represented as NULLs and any predicate (other than IS NULL) on a NULL value is always false. For this purpose, when using the <any count=2>
specification, the rule should use the following join condition:
(Item1.Make is null and Item2.Make = Item3.Make) or (Item2.Make is null and Item1.Make = Item3.Make) or (Item3.Make is null and Item1.Make = Item2.Make)
Within an <any>
element, you can represent the preceding join condition in an abbreviated form using an equal clause. With this syntax, the join condition works well with any value assigned to the count attribute of the <any>
element, such as shown in the following example:
<condition>
<any count=2 equal="Item1.Make, Item2.Make, Item3.Make">
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</any>
</condition>
The equality joins among primitive events of a composite event are very common and thus supports this abbreviated syntax for <and>
element as well, as shown in the following example:
<condition>
<and equal="Item1.Make, Item2.Make, Item3.Make">
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</condition>
When you use both equal
and join
attributes in an <and>
or an <any>
element, the join predicates represented by the equal specification are combined (using logical AND) with the join predicates listed with the join
attribute. For example, the following condition matches any two specified items which are of same make and whose total value is greater than 300. (Note the use of NVL functions in the join predicates).
<condition> <any count=2 equal="Item1.Make, Item2.Make, Item3.Make" join="NVL(Item1.Price,0) + NVL(Item2.Price,0) + NVL(Item3.Price,0) > 300"> <object name="Item1"> Accessory = 'Lens' and Price > 100 </object> <object name="Item2"> Accessory = 'Lens Filter' </object> <object name="Item3"> Accessory = 'IR Light' </object> </any> </condition>
The use of equal attribute at the rule class level (instead of each rule) is discussed in Section 3.4.You can use the sequence
attribute (Section 5.2) in an <any>
element to ensure that the matching primitive events happen in the specified order for the rule condition to evaluate to true, shown as follows.
<condition>
<any count=2 sequence="yes">
<object name="Item1"> Accessory = 'Lens' and Price > 100 </object>
<object name="Item2"> Accessory = 'Lens Filter' </object>
<object name="Item3"> Accessory = 'IR Light' </object>
</any>
</condition>
A collection is an event instance formed by grouping a set of primitive events based on some common properties. The common properties shared by the primitive events could be the equality of certain attributes (for example, all the events in a collection have the same identifier) and they can also include some predicates on the content of the primitive events (for example, all primitive event in the collection satisfy the predicate tranType = 'Withdrawal'
).
Consider a rule class configured for three types of primitive events, BankTransaction, Transportation and FieldReport out of which the BankTransaction events are enabled for collection (see Section 4.8). The rule class can now include rule conditions that test some aggregate predicates on bank transaction events - specifically, bank transaction collection events. For example, the following rule condition makes use of the collection element within the rule condition syntax to test some aggregate predicates.
<condition> <collection name="bank" groupby="subjectId" having="SUM(amount) > 10000"> tranType = "Withdrawal" and amount > 1000 </collection> </condition>
With the preceding rule condition, you can consider for collection all the primitive events that match the criteria specified as the collection element's text value (tranType = "Withdrawal" and amount > 1000
). The rule condition uses the value specified for the groupby
attribute of the <collection>
element to create multiple collection events, one for each unique subject identifier (subjectId
). The collection event maintains the summaries of the primitive events that formed it and looses the identities of the individual events. It uses these summaries to compute the aggregate values necessary to evaluate the predicates specified in the having
clause (value assigned to the having
attribute) of the <collection>
element. As new primitive events occur, it computes necessary aggregate values incrementally and the predicates in the having
clause are evaluated. When the condition specified in the having
clause evaluates to true, it considers the rule condition as true and the action associated with the rule is executed. By default, Rules Manager executes the action (or invokes the action callback procedure) synchronously with the last event (time ordered) in the collection. For each new event in the group that keeps the condition in the having
clause true, Rules Manager executes the rule action once. Alternately, you can reset the collection after executing the action by using EXCLUSIVE
or RULE
consumption polices (see Section 4.8).
The conditional expression you specify for the having
clause of the rule condition is in SQL HAVING
clause format with one or more predicates joined by conjunctions and disjunctions. You form the predicates in the having
clause using one of the five aggregate operators, COUNT
, SUM
, AVG
, MIN
, and MAX
, each operating on one of the attributes from the corresponding event structure. Some sample forms of SQL HAVING
clause specification are as follows.
SUM(amount) > 10000 and AVG(amount) >= 1000 SUM(amount) > 10000 and (AVG(amount) >= 1000 or COUNT(*) < 10) MAX(amount) > 5000 or MIN(amount) > 1000
With the previous rule condition syntax, the number of primitive events participating in the collection is monotonically increasing until the collection is reset (by consuming the collection event). Optionally, you can restrict the number of primitive events participating in a collection by using one of the two moving window semantics:
Fixed window size
Fixed window length
The fixed window size specification for collection events enforces a maximum limit on the number of primitive events in a collection by dropping the oldest event with the addition of a new event. For example, you can enhance the previous rule condition to keep summaries for only the last 100 events (time ordered from the last event occurring) in each collection shown as follows.
<condition> <collection name="bank" groupby="subjectId" having="SUM(amount) > 10000" windowsize="100"> tranType = "Withdrawal" and amount > 1000 </collection> </condition>
Alternately, a rule condition can restrict the primitive events in a collection by using a fixed time window, which ends with the last primitive event added to the collection. For example, you can write the previous rule condition to consider only the events occurring in the past 24 hours, shown as follows. You express the window length specification as a fraction of a day.
<condition> <collection name="bank" groupby="subjectId" having="SUM(amount) > 10000" windowlen="1"> tranType = "Withdrawal" and amount > 1000 </collection> </condition>
When a rule condition with collection constructs evaluates to true, a reference to the collection event instance representing a set of primitive events is returned for action execution (in the action callback procedure or the results view). The collection event is of the same type (BankTransaction in previous examples) as the primitive events of which it consists. However, in the collection event, Rules Manager only initializes the attributes on which the primitive events are grouped (native attributes from the collections's group by
clause), while the rest are each set to NULL
. For example, the collection event created for the previous rule condition is a BankTransaction event with just the subjectId
attribute initialized. The rest of the attributes, potentially being different for each primitive event in the collection, are each set to NULL
.
For each collection event that is made available to the action logic, you can obtain the aggregate values computed for the collection by using the collection event identifier and the DBMS_RLMGR.GET_AGGREGATE_VALUE
call (see Section 4.8). If the action logic relies on more aggregate values than those that are computed for applying predicates, you can specify them using the compute
attribute of the <collection>
element. For example, the following rule condition computes the minimum amount value within each collection (in addition to the sum of amounts), which can be fetched into the application at the time of action execution. Each collection event in a rule condition can maintain a total of 5 aggregate values.
<condition>
<collection name="bank" groupby="subjectId"
having="SUM(amount) > 10000"
compute="MIN(amount)"
windowlen="1">
tranType = "Withdrawal" and amount > 1000
</collection>
</condition>
You can use the rule condition syntax for composite events to relate a collection event with another collection event or a primitive event. For example, you can relate a collection event representing a set of bank transactions to a transportation event to form a rule such as "if a subject withdraws over $10,000 in a day and he rents a truck one-way into a restricted area, add him to the NYPD watch list."
ON
BankTransaction(subjectId, amount, tranType, ..) bank,
Transport(subjectId, vesselType, locFrom, locTo, ..) transport
IF
<condition>
<and equal="transport.subjectId, bank.subjectId">
<collection name="bank" groupby="subjectId"
having="SUM(amount) > 10000"
windowlen="1">
tranType = "Withdrawal"
</collection>
<object name="transport">
vesselType = 'TRUCK' and locTo != locFrom and IsRestrictedArea(locTo) = 1
</object>
</and>
</condition>
THEN
PerformAction('ADD2WATCHLIST','NYPD',subjectId)
While relating a collection event with other collections or individual (non-collection) events or both, the attributes listed in its groupby
clause can be used to form join predicates (join
and equal
clauses) across events. For example, a collection event formed with the previous rule has its subjectId
attribute initialized to the subject identifier that is common across all the primitive events in the collection (owing to the collection's group by
clause) and this attribute can be used to join the collection event (bank) with the other events.
The rule application executes the action associated with the previous rule when a bank transaction collection event and a transportation event, both meeting their corresponding criteria, match on their subjectId
attribute. Depending on the order in which the primitive events occur, it executes the action for this rule synchronously either with the following:
The last bank transaction event in the collection that satisfies the having
clause when there is already a transportation event that matches the other criteria, or
The transportation event that satisfies its criteria and bears the same subject identifier as a bank transaction collection event that satisfied its having
clause.
The having
attribute in the <collection>
element can only include predicates involving a single collection. If the conditional expression in the having
clause should relate multiple collections or one collection with other events, you should use the having
attribute of the <and>
element. For example, in the following rule condition managing items in a crate (both considered to be radio-frequency ID (RFID) read events), Rules Manager groups the item primitive events based on their crateid
attribute and compares the aggregate value computed with the capacity
attribute of the crate.
<condition>
<and equal="crate.id, item.crateid"
having="COUNT(item.*) > crate.capacity*0.8">
<object name="crate"/>
<collection name="item" groupby="crateid"/>
</and>
</condition>
The having
clause specified with the <and>
element can refer to any collection or object you define within the <and>
element using extended names (such as item.*
and crate.capacity
). In such conditions, the having
clause acts as the join condition between collections and other primitive events. This combines the aggregate predicate acting as join conditions with the aggregate predicates on specific collections. However, Rules Manager only optimizes for faster evaluation the aggregate predicates you specify with the having
attribute of a <collection>
element. For example, you can extend the previous rule condition to include a predicate on the minimum number of items in a crate, shown as follows, and with this rule, you can consider a collection event for further evaluation only when it has over 50 individual events.
<condition>
<and equal="crate.id, item.crateid"
having="count(item.*) > crate.capacity*0.8">
<object name="crate"/>
<collection name="item" groupby="crateid"
having="COUNT(*) > 50"/>
</and>
</condition>
You can also use the ability to specify aggregate predicates in the having
clause of the <and>
element to relate multiple collections. For example, you can compare two collections of primitive events, one representing the withdrawals and the other representing the deposits, to check the trend on a back account over a period of time.
ON
Deposits (subjectId, amount, ..) dep,
Withdrawals (subjectId, amount, ..) wdr
IF
<condition>
<and equal ="dep.subjectId, wdr.subjectId"
having = "SUM(wdr.amount) > SUM(dep.amount)">
<collection name="wdr" groupby="subjectId" windowlen="30"/>
<collection name="dep" groupby="subjectId" windowlen="30"/>
</and>
</condition>
THEN
Alert (dep.accountId, 'Negative Trend');
In current release, you cannot combine collection constructs in a rule condition with rule conditions with Negation (see Section 5.3) or Any constructs (see Section 5.5).
Footnote Legend
Footnote 1: For simplicity, the examples in this document are shown without the XML entity references for < (<
;), > (>
;), and '(&apos
;) symbols. Within a rule condition, less than is the only symbol that you must specify using an entity reference (<
;) or use within a XML CDATA section. Although it is not mandatory to use entity references for other symbols, they are recommended for compatibility reasons. Following the SQL naming convention, all the values specified for XML attributes and elements are case-insensitive. Case is preserved only if a value appears within quotes.