1. 程式人生 > >Esper事件處理引擎_15_EPL 語法_7_Patterns_2_模式匹配

Esper事件處理引擎_15_EPL 語法_7_Patterns_2_模式匹配

package com.framework_technology.esper.epl;

import com.framework_technology.esper.javabean.Apple;
import com.framework_technology.esper.javabean.Banana;
import com.framework_technology.esper.javabean.Orange;

/**
 * API - 6.5. Pattern Operators
 *
 * @author wei.Li by 14-8-13.
 */
public class EPL_7_Patterns_2 {

    /**
     *
     ####6.5.1. Every
     參考{@link #every()} 方法中epl1-epl4 語句
     ==========================
     事件的進入順序如下:

     A1   B1   C1   B2   A2   D1   A3   B3   E1   A4   F1   B4

     Table 6.4. 'Every' operator examples

     #Example

     every ( A -> B )

     檢測到的A事件後,通過B項。在當B出現的模式相匹配的時候。
     那麼模式匹配重新啟動,並期待在下一個的A事件。

     Matches on B1 for 組合 {A1, B1}
     Matches on B3 for 組合 {A2, B3}
     Matches on B4 for 組合 {A4, B4}


     every A -> B

     該模式每當進入一個B 事件就去匹配他前面的所有A 事件
     Matches on B1 for 組合 {A1, B1}
     Matches on B3 for 組合 {A2, B3} and {A3, B3}
     Matches on B4 for 組合 {A4, B4}


     A -> every B

     該模式觸發A 事件後,每進入一個B 事件都觸發
     Matches on B1 for 組合 {A1, B1}.
     Matches on B2 for 組合 {A1, B2}.
     Matches on B3 for 組合 {A1, B3}
     Matches on B4 for 組合 {A1, B4}


     every A -> every B

     通過每個B 事件觸發每個A 事件
     Matches on B1 for 組合 {A1, B1}.
     Matches on B2 for 組合 {A1, B2}.
     Matches on B3 for 組合 {A1, B3} and {A2, B3} and {A3, B3}
     Matches on B4 for 組合 {A1, B4} and {A2, B4} and {A3, B4} and {A4, B4}




     #考慮三個事件互相跟隨的表示式

     every (A -> B -> C)
     該模式首先查詢A事件。當A事件到來時,它等待B事件。 B事件到達後,該模式尋找一個C事件。
     假設B事件以及C事件之間的第二A2事件到達。該模式將忽略A2事件因為它的再想找一個C事件。
     最後,當C事件到模式後激發匹配。然後,引擎將重新啟動,開始尋找下一個A事件進入。


     every A -> B -> C
     這種模式為每個A之後,無論何時在A事件到達事件,通過A,B事件,然後一個C事件匹配成功。
     請注意,對於每一個到達的A 事件後,將啟動一個新的子表示式尋找 B事件,然後是C,輸出匹配事件的每一個相結合的表示式



     6.5.1.2. Limiting Subexpression Lifetime 限制子表示式
     =======================================================
     事件的進入順序為
     A1   A2   B1

     這種模式對B1的到來匹配和輸出兩個事件(長度2 ,如果使用一個監聽器陣列) 。這兩個事件是組合{ A1,B1 }和{ A2,B1 }
     every a=A -> b=B

     下一個模式的B1到達匹配僅輸出最後一個A 事件,是結合{ A2,B1 }
     every a=A -> (b=B and not A)
     參考{@link #every()} 方法中epl5 語句




     ####6.5.1.3. Every Operator Example 操作例項
     =======================================================

     every A  -> (B -> C) where timer:within(1 hour)

     首先,該模式如上面從來沒有停止尋找事件A 事件。
     當A1到達時,該模式啟動一個新的子表示式A1保持在記憶體中,並查詢任何B項。與此同時,它也一直在尋找更多的à事件。
     當A2到達時,該模式啟動一個新的子表示式,保持A2在記憶體中,並查詢任何B項。與此同時,它也一直在尋找更多的à事件。
     A2的到來後,有3子表示式活動:

     與A1的第一個有效的子表示式在記憶體中,尋找任何B項。
     與A2的第二個活躍的子表示式在記憶體中,尋找任何B項。
     第三個積極的子表示式,尋找下一個A的事件。

     在上面的圖中,我們指定了一個1小時的使用壽命為子表示式找B和C的事件。
     因此,如果沒有B和沒有C事件A1後,在1小時內到達,第一個子表示式消失。
     如果沒有B而沒有C A2事件後1小時內到達,計算第二個子消失。
     然而,第三子表示式停留四處尋找多項的活動。
     如上圖所示,從而在圖案上的C1到來的組合{ A1,B1, C1 } ,併為組合{ A2 ,B1,C1 } ,只要A1和A2的一個小時之內使B1和C1到達匹配。
     現在你可能會問如何在{ A1  B1,C1 }和{ A2 ,B2,C2 } ,而不是匹配,
     因為你可能需要關聯一個給定的屬性。例如 id 的關聯 every a=A -> (B(id=a.id -> C(id=a.id)) where timer:within(1 hour)


     ####6.5.2. Every-Distinct 欄位值去重複

     語法規則:
     every-distinct(distinct_value_expr [, distinct_value_exp[...][, expiry_time_period])

     Example示例:
     every-distinct(s.sensor) s=Sample
     every-distinct(a.aprop, b.bprop) (a=A and b=B)
     every-distinct(a.aprop) a=A -> b=B(bprop = a.aprop)

     // 無效的,過濾性事件沒有標籤
     every-distinct(aprop) A
     // 無效的: property not from a sub-expression of every-distinct
     a=A -> every-distinct(a.aprop) b=B

     every-distinct(a.aprop) (a=A and not B)
     every-distinct(a.timestamp, 10 seconds) a=A

     //這個 a.timestamp 在這個語句是不會過期的,不推薦這種寫法
     every-distinct(a.timestamp) a=A where timer:within(10 sec)




     ####6.5.3. Repeat 重複發生操作

     語法規則:
     [match_count] repeating_subexpr

     此模式觸發最後5個到達的事件
     [5] A

     括號必須用於巢狀模式的子表示式。這種模式觸發當最後任何五個(A或B)到達的事件:
     [5] (A or B)

     沒有括號的模式語義變化,根據前面描述的運算子優先順序。
     這種模式當最後一共有五事件或一個事件到達,哪個到達哪個最先發生:
     [5] A or B

     標籤可以運用名字在sub-expressions或者事件過濾器表示式的模式中。
     下一個模式尋找A事件之後的B事件,和第二個A事件之後第二個B事件。
     輸出事件提供索引和陣列屬性相同的名稱:select a, a[0], a[0].id, a[1], a[1].id
     from pattern [ every [2] a=A ]
     [2] (a=A -> b=B)

     由於模式匹配返回多個事件,應該將輸出使用下標標記為一個數組,例如:
     select a[0].id, a[1].id from pattern [every [2] (a=A and not C)]





     ####6.5.4.1. Unbound Repeat 釋放重複發生的操作

     引擎匹配repeated_pattern_expr模式直到end_pattern_expr子表示式的求值結果為true停止執行。

     語法規則:
     repeated_pattern_expr until end_pattern_expr

     這個模式,不斷尋找A事件,直到B事件到達:
     A until B

     巢狀模式sub-expressions必須放置在括號,操作 until 優先順序大於模式。
     這個示例收集所有A或B事件10秒並將接收到的事件在索引屬性' A '和' B ':
     (a=A or b=B) until timer:interval(10 sec)

     Bound Repeat - Bounded Range 繫結重複-限制範圍

     下面的模式至少需要3個A 事件的匹配
     如果一個B 事件 在3個A 事件到達之前到達,表示式返回 false ,匹配停止
     [3:] A until B

     下面的模式當 C or D 事件到達時, 無論發生了多少個A 或者B 事件:
     如果A 或者B 事件到達數量>3 ,引擎模式停止增加 A 或者B 的事件
     標籤也只可以匹配前3個
     [:3] (a=A or b=B) until (c=C or d=D)

     下面的模式匹配2個A 事件後的B 事件
     在B 事件中做過濾條件為僅當B 事件中的 beta 的值在第一個A 事件 id 值或者第二個A 事件 id 值中
     [2] A -> B(beta in (a[0].id, a[1].id))

     下面的select子句宣告展示不同的方式訪問標記的事件:
     select a, a[0], a[0].id, a[1], a[1].id from pattern [ every [2] a=A ]

     1.標籤本身可以用來選擇一組潛在的事件。例如,上面的“a”表示式返回一個數組的基本事件的事件型別。
     2.標籤作為一個索引屬性返回底層事件索引。例如,“[0]”表示式返回第一個基本事件,或null如果沒有這樣一個事件被重複操作符匹配。
     3.標記巢狀,索引屬性返回底層事件在索引的屬性。例如,“[1]。id的表示式返回id的屬性值的第二個事件,或null如果沒有這樣的第二個事件被重複操作符匹配。

     你可能不會使用索引標記子表示式中定義的重複操作符相同的子表示式。
     例如,在以下模式重複操作符的表示式(a = b()- > =(id =[0].id))和標籤不能使用索引形式在過濾事件b:
     // 無效的寫法
     every [2] (a=A() -> b=B(id=a[0].id))

     // 有效的
     every [2] (a=A() -> b=B(id=a.id))

     */


    /**
     * every
     *
     * @return epl1
     */
    protected static String every() {

        //every A -> B
        String epl1 = "select a.*  from pattern[every a=" + Apple.CLASSNAME + " -> b=" + Banana.CLASSNAME + "]";

        //every ( A -> B )
        String epl2 = "select a.price  from pattern[every (a=" + Apple.CLASSNAME + " -> b=" + Banana.CLASSNAME + ")]";

        //every A -> every B
        String epl3 = "select a.*  from pattern[every a=" + Apple.CLASSNAME + " -> every b=" + Banana.CLASSNAME + "]";

        // A -> every B
        String epl4 = "select a.*  from pattern[ a=" + Apple.CLASSNAME + " -> every b=" + Banana.CLASSNAME + "]";

        // every a=A -> (b=B and not A)
        String epl5 = "select a.*  from " +
                "pattern[ every a=" + Apple.CLASSNAME + " -> ( b=" + Banana.CLASSNAME + " and not " + Apple.CLASSNAME + " )]";

        return epl5;
    }

    /**
     * @return epl
     */
    protected static String everyOperatorExample() {
        //every A  -> (B -> C) where timer:within(1 hour)
        String elp1 = "select a.price  from " +
                "pattern[ every a=" + Apple.CLASSNAME + " -> ( b=" + Banana.CLASSNAME + " -> o=" + Orange.CLASSNAME + ")" +
                " where timer:within(1 hour)]";
        return elp1;
    }


    /**
     * every-distinct
     *
     * @return epl
     */
    protected static String distinct() {
        //every A  -> (B -> C) where timer:within(1 hour)
        String elp1 = "select a.price from " +
                "pattern[ every-distinct(a.price , b.id) (a=" + Apple.CLASSNAME + " ->  b=" + Banana.CLASSNAME + ")]";
        return elp1;
    }

}