ヘッダーをスキップ
Oracle® Complex Event Processing CQL言語リファレンス
11g リリース1(11.1.1.4.0)
B61613-02
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

13 ユーザー定義関数

ユーザー定義関数を使用して、組込み関数を使用する場合よりも高度な操作やアプリケーション固有の操作をストリーム・データに対して実行します。

詳細は、1.1.11項「関数」を参照してください。

13.1 Oracle CQLのユーザー定義関数の概要

ユーザー定義関数をJavaで作成し、Oracle CQLやOracle CQL組み込み関数には用意されていない機能を提供できます。集計値または単一値(非集計)を返すユーザー定義関数を作成できます。

たとえば、次の場所でユーザー定義関数を使用できます。

ユーザー定義関数をOracle CQL問合せで使用できるようにするには、ユーザー定義関数の実装クラスが含まれたJARファイルをOracle CEPサーバー・クラスパスに配置するか、JARファイルを含めるようにOracle CEPサーバー・クラスパスを変更する必要があります。

詳細は、以下を参照してください。

13.1.1 ユーザー定義関数の種類

oracle.cep.extensibility.functionsパッケージのクラスを使用すると、次の種類のユーザー定義関数を作成できます。

オーバーロード関数の作成、および組込み関数のオーバーライドができます。

13.1.1.1 ユーザー定義単一行関数

単一行ユーザー定義関数は、問合せのストリームまたはビューの各行ごとに単一の結果行を返す関数(たとえば、concat組込み関数のような動作です)。

詳細は、「ユーザー定義の単一行関数の実装方法」を参照してください。

13.1.1.2 ユーザー定義集計関数

ユーザー定義集計は、com.bea.wlevs.processor.AggregationFunctionFactoryを実装し、単一のタプルのかわりにタプルのグループに基づいて単一の集計結果を返す関数(たとえば、sum組込み関数のような動作です)。

可能な場合は、増分処理を行うように集計関数を実装することを検討します。これにより、新しいイベントの到着時の(再)計算コストがこれまでのイベントの合計数ではなく新しいイベントの数に比例するようになるため、スケーラビリティとパフォーマンスが向上します。

詳細は、「ユーザー定義の集計関数の実装方法」を参照してください。

13.1.2 ユーザー定義関数のデータ型

表13-1に、ユーザー定義関数の実装および登録で指定できるデータ型を示します。

表13-1 ユーザー定義関数のデータ型

Oracle CQLデータ型 同等のJavaデータ型

bigint

java.lang.Long

char

java.lang.String

double

java.lang.Double

float

java.lang.Float

int

java.lang.Integer

Object

java.lang.Object


Oracle CQLデータ型の列は、ユーザー定義関数の登録に使用するOracle CQL文で指定できるデータ型を示します。同等のJavaデータ型の列は、ユーザー定義関数の実装で使用できる同等のJavaデータ型を示します。

実行時、Oracle CEPではOracle CQLデータ型とJavaデータ型の間のマッピングを行います。ユーザー定義関数でリストにないデータ型が返された場合は、Oracle CEPでClassCastExceptionがスローされます。

データ変換の詳細は、2.3.4項「データ型変換」を参照してください。

13.1.3 ユーザー定義関数とOracle CEPサーバー・キャッシュ

Oracle CQL文またはユーザー定義関数からOracle CEPキャッシュにアクセスできます。

詳細は、以下を参照してください。

  • Eclipse用Oracle Complex Event Processing開発者ガイドのキャッシュの構成に関する項

  • Eclipse用Oracle Complex Event Processing開発者ガイドのOracle CQL文からのキャッシュへのアクセスに関する項

  • Eclipse用Oracle Complex Event Processing開発者ガイドのOracle CQLユーザー定義関数からのキャッシュへのアクセスに関する項

13.2 ユーザー定義関数の実装

この項では、次の内容について説明します。

詳細は、13.1項「Oracle CQLのユーザー定義関数の概要」を参照してください。

13.2.1 ユーザー定義の単一行関数の実装方法

ユーザー定義の単一行関数を実装するには、関数を実行するために呼び出すpublicコンストラクタとpublicメソッドを提供するJavaクラスを実装します。

ユーザー定義の単一行関数を実装するには:

  1. 例13-1に示すように、Javaクラスを実装します。

    13.1.2項「ユーザー定義関数のデータ型」に示すように、戻り値のデータ型がサポートされているデータ型に対応していることを確認します。

    ユーザー定義関数からのOracle CQLキャッシュへのアクセスの詳細は、13.1.3項「ユーザー定義関数とOracle CEPサーバー・キャッシュ」を参照してください。

    例13-1 MyMod.javaユーザー定義単一行関数

    package com.bea.wlevs.example.function;
    
    public class MyMod {
        public Object execute(int arg0, int arg1) {
            return new Integer(arg0 % arg1);
        }
    }
    
  2. ユーザー定義関数のJava実装クラスをコンパイルし、例13-2に示すように、Oracle CEPアプリケーション・アセンブリ・ファイルでクラスを登録します。

    例13-2 Oracle CQLプロセッサのための単一行ユーザー定義関数

    <wlevs:processor id="testProcessor">
        <wlevs:listener ref="providerCache"/>
        <wlevs:listener ref="outputCache"/>
        <wlevs:cache-source ref="testCache"/>
        <wlevs:function function-name="mymod" exec-method=”execute” />
            <bean class="com.bea.wlevs.example.function.MyMod"/>
        </wlevs:function>
    </wlevs:processor>
    

    wlevs:function要素のexec-method属性を使用して、関数を実行するために呼び出すメソッドを指定します。このメソッドはpublicで、名前によって一意に識別できる必要があります(メソッドがオーバーライドされないように)。

    Eclipse用Oracle Complex Event Processing開発者ガイドのwlevs:functionに関する項を参照してください。

  3. 例13-3に示すように、SELECT文のselectリストまたはWHERE句の条件でユーザー定義関数を呼び出します。

    例13-3 Oracle CQLでのユーザー定義単一行関数へのアクセス

    ...
    <view id="v1" schema="c1 c2 c3 c4"><![CDATA[ 
        select
            mymod(c1, 100), c2, c3, c4 
        from 
            S1
    ]]></view>
    ...
    <query id="q1"><![CDATA[ 
        select * from v1 [partition by c1 rows 1] where c4 - c3 = 2.3 
    ]]></query>
    ...
    

13.2.2 ユーザー定義の集計関数の実装方法

ユーザー定義の集計関数を実装するには、com.bea.wlevs.processor.AggregationFunctionFactoryインタフェースを実装するJavaクラスを実装します。

ユーザー定義の集計関数を実装するには:

  1. 例13-4に示すように、Javaクラスを実装します。

    可能な場合は、増分処理を行うように集計関数を実装することを検討します。これにより、新しいイベントの到着時の(再)計算コストがこれまでのイベントの合計数ではなく新しいイベントの数に比例するようになるため、スケーラビリティとパフォーマンスが向上します。例13-4のユーザー定義集計関数では増分処理がサポートされています。

    13.1.2項「ユーザー定義関数のデータ型」に説明されているように、戻り値のデータ型がサポートされているデータ型に対応していることを確認します。

    ユーザー定義関数からのOracle CQLキャッシュへのアクセスの詳細は、13.1.3項「ユーザー定義関数とOracle CEPサーバー・キャッシュ」を参照してください。

    例13-4 Variance.javaユーザー定義集計関数

    package com.bea.wlevs.test.functions;
     
    import com.bea.wlevs.processor.AggregationFunction;
    import com.bea.wlevs.processor.AggregationFunctionFactory;
     
    public class Variance implements AggregationFunctionFactory, AggregationFunction {
     
        private int count;
        private float sum;
        private float sumSquare;
     
        public Class<?>[] getArgumentTypes() {
            return new Class<?>[] {Integer.class};
        }
     
        public Class<?> getReturnType() {
            return Float.class;
        }
     
        public AggregationFunction newAggregationFunction() {
            return new Variance();
        }
     
        public void releaseAggregationFunction(AggregationFunction function) {
        }
     
        public Object handleMinus(Object[] params) {
            if (params != null && params.length == 1) {
                Integer param = (Integer) params[0];
                count--;
                sum -= param;
                sumSquare -= (param * param);
            }
            
            if (count == 0) {
                return null;
            } else {
                return getVariance();
            }
        }
     
        public Object handlePlus(Object[] params) {
            if (params != null && params.length == 1) {
                Integer param = (Integer) params[0];
                count++;
                sum += param;
                sumSquare += (param * param);
            }
            
            if (count == 0) {
                return null;
            } else {
                return getVariance();
            }
        }
     
        public Float getVariance() {
            float avg = sum / (float) count;
            float avgSqr = avg * avg;
            float var = sumSquare / (float)count - avgSqr;
            return var;
        }
     
        public void initialize() {
            count = 0;
            sum = 0.0F;
            sumSquare = 0.0F;
        }
     
    }
    
  2. ユーザー定義関数のJava実装クラスをコンパイルし、例13-5に示すように、Oracle CEPアプリケーション・アセンブリ・ファイルでクラスを登録します。

    例13-5 Oracle CQLプロセッサのための集計ユーザー定義関数

      <wlevs:processor id="testProcessor">
         <wlevs:listener ref="providerCache"/>
         <wlevs:listener ref="outputCache"/>
         <wlevs:cache-source ref="testCache"/>
         <wlevs:function function-name="var">
           <bean class="com.bea.wlevs.test.functions.Variance"/>
         </wlevs:function>
       </wlevs:processor>
    

    Eclipse用Oracle Complex Event Processing開発者ガイドのwlevs:functionに関する項を参照してください。

  3. 例13-6に示すように、SELECT文のselectリストまたはWHERE句の条件でユーザー定義関数を呼び出します。

    例13-6 Oracle CQLでのユーザー定義集計関数へのアクセス

    ...
    <query id="uda6"><![CDATA[ 
        select var(c2) from S4[range 3] 
    ]]></query>
    ...
    

    実行時、ユーザー定義の集計が実行され、該当するウィンドウで新しいイベントがアクティブになった場合は集計を再計算する必要があります(集計が定義されているセットに新しいメンバーが追加されたため)。これを行うため、Oracle CEPでは適切なhandlePlus*メソッドを呼び出して、(アクティブなセット全体のかわりに)新しいイベントのみを適切なハンドラ・コンテキストに渡します(例13-4を参照)。新しいイベントを含めるようにこの状態を更新できるようになります。このようにして、増分的な方法で集計が再計算されます。

    同様に、該当するウィンドウのイベントが期限切れになった場合は集計を再計算する必要があります(集計が定義されているセットからメンバーが失われたため)。これを行うため、Oracle CEPでは適切なhandleMinusメソッドを呼び出して、(アクティブなセット全体のかわりに)期限切れのイベントのみを適切なハンドラ・コンテキストに渡します(例13-4を参照)。ここでも、増分的な方法でイベントの期限切れに対応するように、ハンドラ・コンテキストの状態を増分的に更新できます。