Oracle® Database Rules Manager and Expression Filter Developer's Guide 11g Release 1 (11.1) Part Number B31088-01 |
|
|
View PDF |
Rules Manager rule conditions are based on the SQL WHERE clause format and are defined on the attributes of the event structure. For the travel services example, the rule condition is expressed using the attributes: Airline
, ToCity
, Return
, and Depart
. Rule conditions defined 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 all rule conditions are embedded within XML <condition> tags. Additional XML tags are defined 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, a rule condition defined on a primitive event will evaluate to true or false instantaneously. In contrast, a rule condition defined on a composite event may have intermediate states, depending on the subset of the primitive events that are available. For example, a rule defined on a composite event constructed from three primitive events can be defined to fire if any two of the three primitive event conditions are true.
To support rule conditions on composite events, additional XML tags are used 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, the previous rule condition can be represented 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. The rule condition in this format can be inserted into the rlm$rulecond
column of the corresponding rule class table. XML tags are provided to support more complex rule constructs. These tags are summarized in Figure 5-1 and Table 5-1 and are described in Section 5.2 through Section 5.5.
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 can be specified using the any operator.
The operator any evaluates to true if any of the primitive event conditions evaluated to true.
The operator any 2 evaluates to true if any 2 or more of the primitive event conditions evaluated to true.
In general, the any operator is parameterized with a count argument, which will evaluate to true if any count of the primitive event conditions evaluate to true.
Sequenced subsets of primitive events can be specified in a number of ways:
Using a Join with a time constraint. The time constraint can be used to impose a partial order over the event instances.
Combinations of and with a sequence tag.
The sequence tag requires a specific ordering of primitive events.
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 is specified using the by option of the not or notany tag:
The not by tag with a timestamp parameter can be used to detect the non-occurrence of a primitive event within a specific time interval.
The notany by tag can be used 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 Appendix F in the Rule Condition section. 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 |
---|---|---|---|---|---|
condition |
Element |
None |
condition |
--- |
Denotes a conditional expression |
and |
Element |
condition |
condition/and |
One |
Combines predicates |
any |
Element |
condition |
condition/any |
One |
A substitute for "or"; true if any condition is met |
not |
Element |
and |
and/not |
One, as last child element |
Logical negation |
notany |
Element |
and |
and/notany |
One, as last child element |
Logical negation; detects non-occurrence |
object |
Element |
condition and any not notany |
condition/object and/object any/object not/object notany/object |
One Two or more objects Two or more objects One object Two or more objects |
Primitive event |
collection |
Element |
condition and |
condition/collection and/collection |
One Two or more in combination with object |
Collection event |
join |
Attribute |
and any not notany |
and/@join any/@join not/@join notany/@join |
One One One One |
Joins predicates |
sequence |
Attribute |
and any |
and/@sequence any/@sequence |
One One |
Specifies an ordered sequence Specifies any ordered sequence |
equal |
Attribute |
and any |
and/@equal any/@equal |
One One |
Joins predicates |
count |
Attribute |
any notany |
any/@count notany/@count |
One One |
Any n semantics Any n semantics |
by |
Attribute |
not notany |
not/@by notany/@by |
One One |
Deadline for non-occurrence Deadline for non-occurrence |
name |
Attribute |
object |
object/@name |
One |
Object name |
collection |
collection/@name |
Collection name |
|||
ref |
Attribute |
object |
object/@ref |
One |
Reference to a shared condition |
groupby |
Attribute |
collection |
collection/@groupby |
One |
Group by specification for the collection |
having |
Attribute Attribute |
collection and |
collection/@having and/@having |
One One |
Having clause for the collection Having clause joining multiple collections |
compute |
Attribute |
collection |
collection/@compute |
One |
Additional aggregate function to compute for the collection |
windowlen |
Attribute |
collection |
collection/@windowlen |
One |
Moving window spec for collection |
windowsize |
Attribute |
collection |
collection/@windowsize |
One |
Moving window spec for collection |
The rules defined 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 is supported using the implicit timestamp attribute (rlm$crtTime
) that is included in each primitive event participating in a composite event.
The event creation times in the primitive events are used to enforce and detect sequencing in rule applications. For example, the rule considered in the travel services application can specify an additional predicate to offer the promotion only if the AddRentalCar
event is generated after the AddFlight
event. The rule condition can be extended 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. The sequence attribute can be replaced 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>
Sequencing can be used 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). The rlm$CrtTime
attribute in the primitive event type can also be used 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. This is indicated in the boldfaced text of the following example where the value 1 means one day. See Oracle Database Advanced Application Developer's Guide for more information about performing date/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, the rlm$CrtTime
attribute is treated as any other attribute in the event structure. However, when a value is not specified 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.
Rules with negation in their conditions are typically used 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, the rule is defined 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, the rule condition for the order tracking rule can be captured as follows, where the boldfaced text in the following example, "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.The <notany>
element can be used in place of the <not>
element to support a notion of disjunction within the negation rule.
At the time of activation, the by
attribute of the <not>
element is executed to compute the deadline for the primitive events in the <not>
element. The value for the by
attribute can be expressed 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, the rule condition in the preceding example can also be expressed 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 the shipment is expected 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).
Rules involving negation constructs can be used 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. A <not>
element without a hard deadline (no by
attribute) can be used to define such rules.
Consider a composite event with three primitive events: PlaceOrder
, PaymentReceived
, and ShipOrder
. A rule can be used 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, the composite event structure and the rule condition are represented 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). The sequence="yes" (Section 5.2) property, such as shown in the following example, can be used 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, the deadline for the PaymentReceived
event is determined by the occurrence of the ShipOrder
event, which follows the corresponding PlaceOrder
event. In effect, the action associated with the preceding rule condition will be executed if the ShipOrder
event is detected before the PaymentReceived
event for a particular order.
The negation construct can often be used 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
. Such rule conditions can be expressed 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, they (primitive events) can be used 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), the join
attribute for the <not>
element can be used. 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. Rules can be defined 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, the composite event structure can be modeled 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, the events can be configured 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, the preceding condition can be expressed 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 the element names Item1
, Item2
, and Item3
are used 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 considered in a rule condition with set semantics. Also, following standard SQL semantics, aggregate operators cannot be used 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, the rule class should be configured 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. This is achieved 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 defined for the composite event may need to match only one of the three primitive events. For this example, the composite event structure and the rule condition are represented 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, the count
attribute of the <any>
element can be used, 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. The condition for this rule can be represented 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. This new rule condition can be represented 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, the preceding rule can be extended 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), this can be posed 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, similar join predicates cannot be used 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, the preceding join condition can be represented 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 this abbreviated syntax is supported 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 both equal
and join
attributes are used 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.The sequence
attribute (Section 5.2) can be used in an <any>
element to ensure that the matching primitive events happen in the specified order for the rule condition to evaluate to true.
<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 a 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 transType = '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, all the primitive events that match the criteria specified as the collection element's text value (tranType = "Withdrawal" and amount > 1000
) are considered for collections. The value specified for the groupby
attribute of the collection
element is used 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. These summaries are used 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, necessary aggregate values are computed incrementally and the predicates in the having
clause are evaluated. When the condition specified in the having
clause evaluates to true, the rule condition is considered true and the action associated with the rule is executed. By default, the action is executed (or the action callback procedure is invoked) 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, the rule action is executed once. Alternately, the collection can be reset after executing the action by using EXCLUSIVE or RULE consumption polices (see Section 4.8).
The conditional expression specified for the having
clause of the rule condition is in SQL-HAVING clause format with one or more predicates joined by conjunctions and disjunctions. The predicates in the having clause can be formed 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 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, the number of primitive events participating in a collection can be restricted 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, the previous rule condition can be enhanced 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, the previous rule condition can be rewritten to consider only the events occurring in the past 24 hours, shown as follows. The window length specification is expressed 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, only the attributes on which the primitive events are grouped (native attributes from the collections's GROUP BY clause) are initialized, while the rest are set to NULLs. 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 set to NULLs.
For each collection event that is made available to the action logic, the aggregate values computed for the collection can be obtained 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, they can be specified 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>
The rule condition syntax for composite events can be used to relate a collection event with another collection event or a primitive event. For example, a collection event representing a set of bank transactions can be related 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 action associated with the previous rule is executed 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, the action for this rule is executed 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, the having
attribute of the and
element should be used. For example, in the following rule condition managing items in a crate (both considered to be RFID read events) the item primitive events are grouped based on their crateid
attribute and the aggregate value computed is compared 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 defined 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. The aggregate predicate acting as join conditions can be combined with the aggregate predicates on specific collections. However, only the aggregate predicates specified with the having
attribute of a collection
element are optimized for faster evaluation. For example, the previous rule condition can be extended to include a predicate on the minimum number of items in a crate, shown as follows, and with this rule, a collection event is considered 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>
The ability to specify aggregate predicates in the having
clause of the and
element can also be used to relate multiple collections. For example, two collections of primitive events, one representing the withdrawals and the other representing the deposits, can be compared 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, collection constructs in a rule condition cannot be combined 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 must be specified using an entity reference (<
;) or used 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.