SAS Event Stream Processing 5.2: ウィンドウの作成と使用
概要
イベントストリーム処理モデルは、入力イベントストリームがどのように変換され、意味のあるイベントストリ ームに分析されるかを指定します。すべてのモデルにエンジンが搭載されています。エンジンには
1
つ以上の プロジェクトが含まれ、各プロジェクトには1
つ以上の連続クエリが含まれます。連続クエリには、1つ以上の ソースウィンドウと1
つ以上の派生ウィンドウが含まれます。ウィンドウはエッジによって接続されており、エ ッジは関連する方向を持っています。SAS Event Stream Processing
は、それぞれ特殊な目的を持ったさまざまな派生ウィンドウタイプをサポートしています。
表 1 ウィンドウタイプ
ウィンドウタイプ 説明
ソースウィンドウ すべてのイベントストリームは 、パブリッシュされたり、ソースウィンドウにインジェクトさ れたりして、連続クエリを入力する必要があります。イベントストリームは、他のウィンドウ タイプにパブリッシュまたはインジェクトすることはできません。
計算ウィンドウ 入力イベントストリームフィールドの計算操作を通じて入力イベントの出力イベントへの1 対1変換を可能にします。
コピーウィンドウ 親ウィンドウのコピーを作成します。コピーを作成すると、新しいイベント状態保持ポリシー を設定することができます。保持ポリシーは、ソースウィンドウおよびコピーウィンドウでの み設定できます。
コピーウィンドウのイベント状態の保持は、ウィンドウが挿入専用ではなく、ウィンドウイン デックスが
pi_EMPTY
に設定されていない場合にのみ設定できます。後続のすべての兄弟ウ ィンドウが保持管理の影響を受けます。イベントは、ウィンドウの保持ポリシーを超えると削 除されます。集計ウィンドウ 非キーフィールドが計算される点で計算ウィンドウに似ています。集計ウィンドウは、グルー プごとの条件のキーフィールドを使用します。すべての一意キーフィールドの組み合わせが、
集計ウィンドウ内で独自のグループを形成します。同じキーの組み合わせを持つすべてのイベ ントは、同じグループの一部です。
カウンタウィンドウ モデルを通ってストリーミングされているイベントの数とそれらが処理されているレートを確 認できます。
ウィンドウタイプ 説明
フィルタウィンドウ 登録されたブールフィルタ関数または式を使用します。この関数または式は、フィルタウィン ドウにどの入力イベントが許可されるかを決定します。
関数ウィンドウ さまざまな種類の関数を使用してイベントデータを操作または変換できます。関数ウィンドウ 内のフィールドは階層構造にすることができ、Web分析などの応用に役立ちます。
ジオフェンスウィンドウ ウィンドウを作成して、イベントストリームの場所が関心領域の内側にあるのか、関心領域に 近いのかを判断できます。
結合ウィンドウ 2つの入力ウィンドウと結合タイプをとります。1対多、多対1、多対多の等価結合をサポート します。内部結合と外部結合の両方がサポートされています。
通知ウィンドウ メール、ショートメッセージまたはマルチメディアメッセージを 使用して通知が送信できます。
任意の数の配布チャネルを作成して通知を送信することができます。通知ウィンドウは、関数 ウィンドウと同じ基本言語と関数を使用します。
パターンウィンドウ 関心があるイベント(EOI)の検出を有効にします。このウィンドウタイプで定義されたパター ンは、宣言された関心があるイベントを論理的に接続する式です。
パターンウィンドウを定義するには、関心があるイベントを定義し、次にこれらの関心がある イベントを演算子を使用して接続する必要があります。サポートされる演算子は、"AND"、
"OR"、"FBY"、"NOT"、"NOTOCCUR"、"IS"です。演算子はオプションの一時的条件を受け入 れることができます。
プロシジャウィンドウ 任意の数の入力ウィンドウや各入力ウィンドウの入力ハンドラ関数の指定(すなわち、イベント ストリーム)を可能にします。
テキストカテゴリウィン
ドウ 受信イベントのテキストフィールドを分類できます。テキストカテゴリウィンドウは挿入専用 です。テキストフィールドは、スコアを持つ0個以上のカテゴリを生成することができます。
このオブジェクトにより、SAS Contextual Analysisのライセンスを取得したユーザーは、MCO ファイルを使用してテキストカテゴリウィンドウを初期化できます。
テキストコンテキストウ
ィンドウ 非構造化文字列フィールドから分類された用語を抽象化できます。
このオブジェクトを使用すると、SAS Contextual Analysisのライセンスを取得したユーザーは Litiファイルを使用してテキストコンテキストウィンドウを初期化できます。このウィンドウ タイプを使用して、イベント入力からの文字列フィールドを分析し、分類された用語を検索し ます。その用語から生成されたイベントは、他のウィンドウタイプで分析できます。たとえば、
パターンウィンドウは、テキストコンテキストウィンドウの後に、関心のあるツイートパター ンを探すことができます。
テキストセンチメントウ
ィンドウ 指定された受信テキストフィールド内のテキストのセンチメントとその出現確率を決定しま す。センチメント値は“正“、“中立“または“負“です。確率は0と1の間の値です。テキストセン チメントウィンドウは挿入専用です。
このオブジェクトを使用すると、SAS Sentiment Analysisのライセンスを取得したユーザー は、SAMファイルを使用してテキストセンチメントウィンドウを初期化できます。
テキストトピックウィン
ドウ イベントでSAS Text Miner分析を実行します。テキストトピックウィンドウは、ドキュメント から文字列フィールドとしてテキストを受け取り、処理します。テキストマイニング分析モデ ルは、分析ストア(ASTORE)ファイルを使用してテキストトピックウィンドウに入ります。
結合ウィンドウ 1つ以上のストリームを同じスキーマとマージする簡単な結合を指定します。
SAS Event Stream Processing
では、追加の一連のウィンドウタイプが提供されます。詳細については、XisError:
Unexpected access error occurred for cross reference book title for alias = "espan", locale = "ja", and source file
= "sas.xis.doc.xml://espcreatewindows/xml/window_overview.xml". This attribute is being referenced by project
espcreatewindows(ja):dev/vert-ibdoc7.を参照してください。
式の使用
式の概要
イベントストリーム処理アプリケーションでは、式を使用して次の項目を定義できます。
n フィルタウィンドウのフィルタ条件
n 計算、集計、および結合ウィンドウでの非キーフィールド計算 n 関心のあるイベントのウィンドウパターンの一致
n ウィンドウ出力スプリッタ/スロットの計算(たとえば、式を使用して生成されたイベントを送信する場所を評 価します)
パターンマッチングを除き、式の代わりにユーザー定義関数を使用することができます。パターンマッチングで は、式を使用する必要があります。
式をそれぞれのウィンドウに書き込んで登録するのは、Cで同等のユーザー定義関数を書くよりも簡単です。式 は関数よりも遅く実行されます。非常に待機時間の少ないアプリケーションでは、ユーザー定義関数を使用し て、式の解析と処理のオーバーヘッドを最小限に抑えることができます。
可能であれば、プロトタイプ式を使用してください。結果に基づいて、必要に応じて最適化したり、関数に変換 してください。ほとんどのアプリケーションでは、関数の代わりに式を使用しますが、パフォーマンスの向上が 重要な場合は関数を使用できます。
式の指定方法については、XisError: Unexpected access error occurred for cross reference book title for alias =
"engelref", locale = "ja", and source file = "sas.xis.doc.xml://espcreatewindows/xml/
dataflux_expression_lang.xml". This attribute is being referenced by project espcreatewindows(ja):dev/vert- ibdoc7.を参照してください。
注:
SAS Event Stream Processing
では、Expression Engine Language用に文書化された機能のサブセットが 使用されます。このサブセットは、イベントストリーム処理の必要性に対して堅牢です。各式ウィンドウとウィンドウスプリッタには、独自の式エンジンインスタンスがあります。式エンジンインスタ ンスは、ウィンドウによって処理される各イベントのウィンドウ式とスプリッター式を実行します。エクスプレ ッションエンジンが式ウィンドウまたはウィンドウスプリッターで使用される前に(つまり、それらのウィンドウ にイベントストリームが入る前に)式エンジンを初期化できます。式エンジンの初期化は、式ウィンドウまたはウ ィンドウ分割式で使用される式エンジン変数の宣言および初期化に役立ちます。また、式で使用される正規表現 を宣言するのにも役立ちます。
式ウィンドウの式エンジンを初期化するには、dfESPexpression_window::expEngInitializeExp()を使用します。
ウィンドウスプリッタの式エンジンを初期化するには、dfESPwindow::setSplitter()を使用します。例は
$DFESP_HOME/examples/cxx/splitter_with_initexpと$DFESP_HOME/examples/cxx/regexにあります。
データ型マッピングについて
SAS Event Stream Processing API
でサポートされているデータ型とExpression Engine Language
でサポート されているデータ型の間には、正確なデータ型マッピングは存在しません。次の表に、サポートされているデータ型のマッピングを示します。
表 2 式データ型マッピングテーブル
イベントストリーム処理式 式 メモと制限
文字列(utf8) 文字列(utf8) 式に渡される文字列は、1024バイ トに切り捨てられることがありま す。ウィンドウ固有の属性
exp‑max‑string=
'N'またはC++window method
dfESPwindow::set_EXP_strMa x(int N)
を使用してウィンドウの 式文字列の最大サイズを設定しま す。日付(2番目の粒度) 日付(2番目の粒度) 秒粒度
タイムスタンプ(マイクロ秒粒度) 日付(2番目の粒度) dfExpressionsの定数ミリ秒はサ ポートされていません。
INT32(32ビット) 整数(64ビット) dfExpressionsの64ビット変換
INT32(64ビット) 整数(64ビット) 64ビット、変換なし
Double(64ビットIEEE) Real(192ビット固定小数) Real192ビット固定小数点、
Double64ビットfloat
金額(192ビット固定小数点) Real(192ビット固定小数) 192ビット固定小数点、変換なし
式でのイベントメタデータの使用
SAS Event Stream Processing
では、イベントのメタデータにアクセスするために使用できる予約語のセットが提供されます。これらの予約語は、フィルタ式、計算式、および結合ウィンドウ式およびウィンドウ出力分割式 で使用できます。パターンウィンドウは挿入専用なので、メタデータはパターンウィンドウ式では使用できませ ん。
予約語 演算コード
ESP_OPCODE
指定されたウィンドウでイベントの演算コードを取得する には、この予約語を使用します。
i-挿入 u-更新
p-アップサート d-削除
Sd-安全な削除
安全な削除では“キーが見つかりません“というERRORは生 成されません。
ESP_FLAGS
指定されたウィンドウ内のイベントのフラグを取得するに は、この予約語を式で使用します。
N-標準 P-部分 R-保持の削除
式言語のグローバル関数の使用
Expression Engine Language
では、ユーザー定義関数(UDF)とも呼ばれるグローバル関数がサポートされてい ます。それらをグローバル関数として登録し、任意の式ウィンドウまたはウィンドウ分割式から参照することが できます。グローバル関数の詳細については、XisError: Unexpected access error occurred for cross referencebook title for alias = "engelref", locale = "ja", and source file = "sas.xis.doc.xml://espcreatewindows/xml/
dataflux_expression_lang.xml". This attribute is being referenced by project espcreatewindows(ja):dev/vert- ibdoc7.を参照してください。
グローバル関数を登録できる
2
つのSAS Event Stream Processing
関数があります。n
dfESPexpression_window::regWindowExpUDF(udfString, udfName, udfRetType)
ndfESPwindow::regSplitterExpUDF(udfString, udfName, udfRetType)
ウィンドウスプリッタまたは式ウィンドウのグローバル関数を登録した後、スプリッタ式またはウィンドウ式で
udfNameを参照できます。イベントが処理される際にudfNameはudfStringに置き換えられます。
フィルタ、計算、結合、パターンの式ウィンドウでは、グローバル関数の使用がサポートされています。集計ウ ィンドウはグローバル関数をサポートしていません。なぜなら、それらの出力フィールドは集計関数を使用した 作成専用であるからです。すべてのウィンドウは、指定されたウィンドウで出力スプリッタのグローバル関数を サポートします。
SAS Data Quality 関数の使用
イベントストリーム処理式は、SAS Data Quality関数の使用をサポートしています。次の関数は、XisError:
Unexpected access error occurred for cross reference book title for alias = "engelref", locale = "ja", and source file = "sas.xis.doc.xml://espcreatewindows/xml/dataflux_expression_lang.xml". This attribute is being referenced by project espcreatewindows(ja):dev/vert-ibdoc7.に完全に記載されています。
n
dq.case
ndq.gender
ndq.getlasterror
ndq.identify
ndq.initialize
ndq.loadqkb
ndq.matchcode
ndq.pattern
ndq.standardizeL
次の
2
つの環境変数を設定する必要があります。n
DFESP_QKB
をSAS Data Quality
インストール配下の共有フォルダに設定します。LinuxシステムにSAS Data Quality
をインストールした後、この共有フォルダは/QKB_root/data/ci/qkb_version_number_no_dotsです(たとえば/QKB/data/ci/22)。
n
DFESP_QKB_LIC
をSAS Data Quality
ライセンスファイルへの完全パス名に設定に変更します。SAS Event Stream Processing
用にSAS Data Quality
を設定した後、これらの関数をイベントストリーム処理式 に含めることができます。これらの関数は、通常、計算ウィンドウの非キーフィールド計算式のイベントフィー ルドを正規化するために使用されます。ソースウィンドウの作成
ソースウィンドウの概要
各連続クエリにはソースウィンドウが必須です。すべてのイベントストリームは 、パブリッシュされたり、ソー スウィンドウにインジェクトされたりして、連続クエリを入力します。イベントストリームは、他のウィンドウ タイプにパブリッシュまたはインジェクトすることはできません。
ソースウィンドウは、通常、1つまたは複数の派生ウィンドウに接続されます。派生ウィンドウは、データ内の パターンを検出したり、データを変換したり、データを集計したり、データを分析したり、データに基づいて計 算を実行したりすることができます。
ソースウィンドウは、インプロセスコネクタまたは実行可能アダプタを介してストリーミングデータまたは生デ ータファイルを受け入れます。ソースウィンドウでは、パブリッシュ/サブスクライブ
API、HTTP
クライアン ト、またはC++モデリング API
からのインジェクションによってデータを受け取ることもできます。イベントインデックスタイプの定義
ソースウィンドウには、プライマリインデックスと保持インデックスがあります。ステートフルインデックスタ イプは
6
つあり、ステートレスインデックスタイプは1
つです。ソースウィンドウのプライマリインデックスタ イプは、プロジェクトの残りの部分のパフォーマンスに影響します。たとえば、ソースウィンドウにインデック スタイプがある場合pi_RBTREE
ウィンドウはステートフルであり、すべての受信イベントを保持します。保持 ポリシーなしでソースウィンドウでイベントを保持すると、ソースウィンドウがステートレスである場合と比べ て、データが連続クエリに読み込まれるため、実質的に多くのメモリが使用されます。インデックスのタイプの詳細については、“プライマリインデックスと特殊インデックスについて”を参照してく ださい。
ソースウィンドウの保持ポリシー
ステートフルなソースとコピーウィンドウに保持ポリシーを定義することができます。保持ポリシーを使用す るには、ウィンドウを挿入専用として指定することはできず、インデックスタイプを
pi_EMPTY
として指定する ことはできません。保持ポリシーは、受信データのフローを時間またはイベント数で制限し、モデルのパフォー マンスを向上させることができます。イベントは、ウィンドウの保持ポリシーを超えた場合にエンジンによって 自動的に削除されます。通常、保持ポリシーが設定されたコピーウィンドウを持つ挿入専用ソースウィンドウに 従います。保持ポリシーの詳細については、次を参照してください。“保持の理解”
挿入専用処理の伝播
挿入だけを受け入れるようにソースウィンドウにフラグを立てることができます。この属性は、次のいずれかの 条件が満たされるまで、派生ウィンドウに伝播します。
n ウィンドウは、挿入専用データを生成しないように決定されます(たとえば、保持のあるウィンドウなど)。
n ウィンドウは、グラフ分析から決定することができない演算コードを生成します。
キー値の自動生成
ソースウィンドウは、受信イベントの識別キーを自動的に生成することができます。キー値を自動的に生成する には、ソースウィンドウが挿入専用で、タイプが
INT64
または文字列のキーが1
つだけ必要です。INT64キー の場合、値は増分カウント(0、1、2、...)です。文字列キーの場合、値はグローバル一意識別子(GUID)です。パブリッシャコネクタ
パブリッシュコネクタは、ソースウィンドウで一意です。ソースウィンドウのパブリッシュコネクタは、次の項 目を決定します。
n データソースのパス
n データソースから受け取ったイベントのデータ型
n 受信データをプロジェクト全体で使用されるイベントに変換することに関連するその他の重要なプロパティ ソースウィンドウのパブリッシャコネクタは、データの読み込み方法と、イベントが派生ウィンドウにプッシュ される形式を決定します。コネクタの必須およびオプションのプロパティは、コネクタエレメントで定義されて います。
ソースウィンドウのスキーマで定義されたフィールドは、プロジェクトに読み込まれ、派生ウィンドウで使用さ れるデータの構造を決定します。
測定ウィンドウの有効化
エンジンには、モデル内のすべてのソースウィンドウで 処理されるイベントの数(および関連するタイムスタン プ)をトレースするための測定ウィンドウを含めることができます。この関数を有効にするには、
metatags.conf
ファイルでenableMetaProject
フィールドの値をtrueに設定する必要があります。_meta_という名前のプロ ジェクトに含まれている_meta_という名前の連続クエリに、測定ウィンドウが設定されます。ソースウィンドウは、デフォルト間隔
5
秒でイベントを測定ウィンドウにインジェクトします。サブスクライブ するアプリケーションは、他のウィンドウと同様に測定ウィンドウに登録することができます。測定ウィンドウは、それ自体、_eventmetering_という名前の特別なソースウィンドウです。これには、次の スキーマがあります。
"project*:string,query*:string,window*:string,currenttime:stamp,lasttime:stamp,numevents:int64"
測定サーバーを起動すると、測定ウィンドウのスキーマの最後に文字列フィールドを追加できます。その後、測 定ウィンドウによって生成されたすべての測定イベントは、それらのフィールドを含みます。これらのフィール ドの値は、いつでも定義または再定義できます。エンジン始動時に定義されていない場合は、値を定義するまで 値がヌルになります。デフォルトの測定間隔を
5
秒間に再設定することもできます。測定サーバーを実行し、meteringhostおよび
meteringport
パラメーターが設定されると、測定ウィンドウへ の各更新は、集計のために測定サーバーに転送されます。コピーウィンドウの作成
コピーウィンドウの概要
コピーウィンドウは、他のタイプの親ウィンドウのコピーです。特定のイベント状態保持ポリシーでイベントを 保持すると便利です。保存ポリシーは、ソースおよびコピーウィンドウでのみ設定できます。
コピーウィンドウの保持ポリシー
コピーウィンドウのイベント状態の保持は、ウィンドウが挿入専用に指定されていない場合やウィンドウインデ ックスが設定されていない場合にのみ設定できます
pi_EMPTY 。すべての子ウィンドウは保持管理に影響され
ます。イベントは、ウィンドウの保存ポリシーを超えると削除されます。保持ポリシーの詳細については、次を参照してください。“保持の理解”
集計ウィンドウの作成
集計ウィンドウの概要
集計ウィンドウは、非キーフィールドが計算される点で計算ウィンドウに似ています。ただし、キーフィールド は指定されており、入力ウィンドウから継承されません。キーフィールドは入力イベントの存在するフィールド に対応する必要があります。受信イベントは、指定されたキーフィールドと同じ値を持つグループ内の各イベン トとともに集計グループに配置されます。
たとえば、次のスキーマが入力イベントに指定されているとします。
"ID*:int32,symbol:string,quantity:int32,price:double"
集計ウィンドウのスキーマを次のように指定するとします。
"symbol*:string,totalQuant:int32,maxPrice:double"
イベントが集計ウィンドウに到着すると、それらは
symbol
フィールドの値に基づいて集計グループに配置され ます。集計フィールド計算関数(C++で記述)または集計ウィンドウに登録されている式は、キー以外のフィール ドに表示する必要があります。この例では、totalQuantとmaxPrice
です。すべてのキー以外のフィールドに は、式または関数を使用する必要があります。これらは混在することはできません。関数または式は、新規作成 イベントが来るたびに引数の1
つとしてイベントのグループとともに呼び出され、1つまたは複数のグループを 変更します。これらのグループは、内部的に
dfESPwindow_aggregate
クラスでdfESPgroupstate
オブジェクトとして管理 されます。すべてのキー以外のフィールドで指定された集計関数または式を実行することによって、グループか ら新規作成イベントが追加または削除されるたびに、各グループが折りたたまれます。集計ウィンドウの目的 は、グループごとに1
つの集計イベントを生成することです。操作の流れ
集計ウィンドウの処理中の操作の流れは次のとおりです。
1 イベントEが到着し、Gと呼ばれる適切なグループが見つけられます。これは、集計ウィンドウのキーフィ ールドに対応する受信イベントの値を調べることによって完了します。
2 イベントEはグループGにマージされます。出力イベントのキーは、Gのグループバイフィールドで形成さ れます。
3 出力スキーマの各非キーフィールドは、グループGを入力として集計関数を呼び出すことによって計算され ます。集計関数は、対応するキー以外のフィールドのスカラー値を計算します。
4 正しい出力イベントが生成され、出力されます。
集計関数の使用
集計関数の概要
集計中に集計ウィンドウに入るイベントは、集計ウィンドウのキーフィールドに基づいてグループに配置されま す。集計関数は各集計で実行され、集計ウィンドウの各非キーフィールドを計算します。
ある意味では、集計ウィンドウは、キーに従って入力イベントを分割します。これらのパーティションは集計グ ループと呼ばれます。集計ウィンドウのキー以外のフィールドに指定されている関数は特殊関数です。値のグ ループを操作し、単一のスカラー値にグループを崩壊させます。
図 1 集計の例
Source Window Schema: id*int32, symbol:string, quant: int32
Retention type: Volume (count=2) Retention sub-type: Sliding
Aggregate Window Schema: symbol*:string, sumQuant: int32
集計ウィンドウのキーはsymbolです。これには、ソースウィンドウから到着するフィールドquantの合計で ある非キーフィールドsumQuantが
1
つだけあります。フィールド値の合計を計算する関数は、ESP_aSum(fieldname)です。ここで、集計ウィンドウには
ESP_aSum(quant)として計算される非キーフィールドが 1
つあります。概念的には、イベントが集計ウィンドウに入ると、そのイベントがグループに追加され、
ESP_aSum(quant)関数が実行され、グループの新規作成合計が
生成されます。集計ウィンドウフィールド計算式の集計関数
集計ウィンドウのフィールド計算式では、次の集計関数を使用できます。
集計関数 返される値
ESP_aAve(fieldname)
グループの平均ESP_aCat(fieldname, stringConstant)
指定されたstringConstantをセパレータとして使用して、集計グループ内の各イベントのフィールド名値を連結し ます。
たとえば、
ESP_aCat(ID, "|")
は集計グループを構成する すべてのIDの区切りリスト"|"を返します。ESP_aCount()
グループ内のイベントの数ESP_aCountDistinct(fieldname)
グループ内のフィールド名で指定された列内の個別の非ヌル値の数
ESP_aCountNonNull(fieldname)
グループ内の指定されたフィールド名の列に非ヌル値を持つイベントの数
ESP_aCountNull(fieldname)
グループ内の指定されたフィールド名の列にヌル値を持つイベントの数
ESP_aCountOpcodes(opcode)
グループの演算コードに一致するイベントの数のカウント
ESP_aFirst(fieldname)
グループに追加された最初のイベントESP_aGUID()
一意の識別子ESP_aLag(fieldname,lag_value)
ラグ値は次の通りです。n
ESP_aLag(fieldname,0) == ESPaLast(fieldname)
n
ESP_aLag(fieldname,1)は 2
番目のラグを返しま す。これは、グループに影響を与えたfieldname の以前の値です。ESP_aLast(fieldname)
グループに影響を与えた最後のレコードのフィールド集計関数 返される値
ESP_aLastNonNull(fieldname)
グループに影響を与えた最後のレコード(非ヌル値)のフィールド
ESP_aLastOpcode()
グループに影響を与える最後のレコードの演算コードESP_aMax(fieldname)
グループの最大値ESP_aMin(fieldname)
グループの最小値ESP_aMode(fieldname)
モード、または最も人気のあるグループESP_aStd(fieldname)
グループの標準偏差ESP_aSum(fieldname)
グループの合計ESP_aWAve(weight_fieldname, payload_fieldname)
加重平均グループ次の関数は常に加算的です。
n
ESP_aAve
nESP_aCount
n
ESP_aCountOpcodes
nESP_aCountDistinct
nESP_aGUID
n
ESP_aLastOpcode
nESP_aMode
nESP_aStd
nESP_aSum
nESP_aWAve
次の関数は、挿入を取得したときにのみ加算されます。
n
ESP_aCat
n
ESP_aCountNonNull
nESP_aCountNull
nESP_aFirst
nESP_aLast
n
ESP_aLastNonNull
nESP_aMax
n
ESP_aMin
次のように、非キーフィールド計算式に組み込み集計関数を簡単に使用できます。
dfESPwindow_aggregate *aw_01;
aw_01 = cq->newWindow_aggregate("aggregateWindow_01", dfESPindextypes::pi_RBTREE,
aggr_schema);
aw_01->addNonKeyFieldCalc("ESP_aSum(quantity)"); // sum(quantity) aw_01->addNonKeyFieldCalc("ESP_aMax(quantity)”); // max(quantity)
集計フィールド式の使用は、集計関数より簡単ですが、処理が遅くなり、関数の数が制限されます。
注:
ESP_aSum、ESP_aMax、ESP_aMin、ESP_aAve、ESP_aStd、および ESP_aWAve
では、フィールド内のヌ ル値は無視されます。したがって、それらは計算に寄与しません。関数
ESP_aSum、 ESP_aFirst、 ESP_aWAve、 ESP_aStd、 ESP_aCount、 ESP_aLast、 ESP_aFirst、
ESP_aLastNonDelete、 ESP_aLastOpCode、 ESP_aCountOpcodes
はすべて相加的です。すなわち、それらは、保持された状態および受信イベントから決定された値から計算することができます。グループ状態を維持する 必要はありません。つまり、これらが
dfESPwindow_aggrgate
インスタンスで使用される唯一の関数であれば、特別な最適化が行われます。集計ウィンドウ処理では、桁違いのスピードアップが可能になります。
dfESPgroupstate
クラスは、グループを集計内に維持するために内部的に使用され、dfESPgroupstate
のインス タンスは集計関数に渡されます。集計関数のシグネチャは次のとおりです。typedef dfESPdatavarPtr (*dfESPaggregate_func)(dfESPschema *is, dfESPeventPtr nep, dfESPeventPtr oep,
dfESPgroupstate *gs);
この定義は、api/dfESPfuncptr.hファイルにあります。
dfESPgroupstate
オブジェクトは、同じグループに属する一連のイベントのコンテナとして機能します。また、非キーフィールドごとに
1
つの状態ベクトルであるdfESPdatavars
の状態ベクトルを保持します。これは、集 計関数がフィールドの状態を格納するために使用できます。これにより、新規作成グループメンバーが到着した ときに、迅速な増分集計関数の更新が可能になります。受信イベントに統計を追加するには集計関数を使用
ESP_aLast(fieldName)集計関数を使用して、受信フィールドを作成された集計イベントに渡すことができます。
これは、集計ウィンドウを使用せずに結合ウィンドウを使用することなく、集計ウィンドウからイベントに統計 を追加する場合に便利です。または、集計ウィンドウの後に結合ウィンドウを使用すると、集計計算またはイベ ントが集計ウィンドウに供給される同じイベントに結合されます。しかし、その場合の結果は最適ではないかも しれません。
たとえば、これが受信イベントスキーマであるとします。
"ID*:int64,symbol:string,time:datetime,price:double"
この受信イベントスキーマを使用して、集計統計を追加するとします。
"ID*:int64,symbol:string,time:datetime,price:double,ave_price:double"
そこでは、同じ"symbol"を持つグループに対して平均値が計算されます。
または、次のスキーマを使用して単一の集計ストリームを定義することもできます。
"ID:int64,symbol*:string,time:datetime,price:double,ave_price:double"
注:
group-by
は集計のキーであり、これは"symbol"です。次に、dfESPwindow_aggregate::addNonKeyFieldCalc(expression)を使用して、このウィンドウの各非キーフ ィールド(この場合は"ID"、"TIME"、"price"および"ave_price")に次の集計関数を登録します。
awPtr->addNonKeyFieldCalc("ESP_aLast(ID)”);
awPtr->addNonKeyFieldCalc("ESP_aLast(time)”);
awPtr->addNonKeyFieldCalc("ESP_aLast(price)”);
awPtr->addNonKeyFieldCalc("ESP_aAve(price)”);
次のイベントが集計ウィンドウに表示されたとします。
insert: 1, "ibm", 09/13/2001T10:48:00, 100.00 insert: 2, "orc", 09/13/2001T10:48:01, 127.00 insert: 3, "ibm", 09/13/2001T10:48:02, 102.00 insert: 4, "orc", 09/13/2001T10:48:03, 125.00
insert: 5, "orc", 09/13/2001T10:48:04, 126.00 集計ストリームは次のようになります。
insert: 1, "ibm", 09/13/2001T10:48:00, 100.00, 100.00 insert: 2, "orc", 09/13/2001T10:48:01, 127.00, 127.00 update: 3, "ibm", 09/13/2001T10:48:00, 102.00, 101.00 update: 4, "orc", 09/13/2001T10:48:01, 125.00, 126.00 update: 5, "orc", 09/13/2001T10:48:01, 126.00, 126.00
aLast(fieldname)を使用して、関連する集計フィールドを追加することで、後続の結合ウィンドウを回避できま
す。これによりモデリングがよりクリーンになります 。集計関数の作成と使用
0、1、2
または3
つの引数で集計関数を書きます。引数は、集計の入力スキーマの整数値式、整数定数、またはフィールド名のいずれかでなければなりません。
最も一般的に使用される集計関数は、入力スキーマフィールド名を持つ
1
つのパラメータ関数です(たとえば、組み込み集計関数
ESP_aMax(fieldname)です)。入力スキーマのフィールド名の場合、入力イベントへのフィー
ルド索引は、フィールドの値ではなく集計関数に渡されます。これは、グループを扱うときに重要です。グルー プ内のすべてのイベントを反復処理し、各入力イベントからイベントインデックスで値を抽出する必要がありま す。集計関数を記述したら、それを
C++コードに埋め込み、イベントストリームプロセッサアプリケーションで使用
します。関数を$DFESP_HOME/examples/cxx/aggregate_userdef/src/functions.cppにコピーします。関 数の名前がMy_Aggregation_Functionであるとします。functions.cppの最後に、集計関数用のラッパー関 数を作成します。// the uMyFunction wrapper:
// every aggregation function must be wrapped like this.
//
int dfESPaggrfunc_uMyFunctionWrapper(dfESPexpEngine::exp_engine_t *e, dfESPexpEngine::exp_sym_value_t *returnval,
int parmcount,
dfESP_EXPsym_value_t **parms) {
return dfESPaggrfunc_Wrapper((void *)my_aggrergation_function, e, returnval, parmcount, parms);
}
ラッパー関数のユーザー定義関数リストに項目を作成します。
// Get all user-defined aggregation functions during initialization //
void add_user_aggrFunctions() {
dfESPengine *e = dfESPengine::getEngine();
dfESPptrList<aggr_function_t *> &uFuncts = e->getUDAFs();
// push back as many user defined functions as you like:
// the parameters are: <callable name>, <function pointer>, // <num args>, <additive flag>, <additive flag for insert only>, // <description>
uFuncts.push_back(new aggr_function_t("USER_uSum_add", (void *)dfESPaggrfunc_uMyFunctionWrapper, "a", true, true, "description"));
}
引数の数、追加フラグ、および説明フィールドをそれに応じて調整します。サンプルコード$DFESP_HOME/
examples/cxx/aggregate_userdef/src/functions.cppには、2つの完全な例があります。サンプルコードと
ともに配布される
makefile
は、aggregate_userdef/pluginsディレクトリに共有ライブラリを生成します。こ のプラグインを$DFESP_HOME/libにコピーし、libdfxesp_udafD‑major.minorという名前を付けます。非加算的集計関数の作成
最も単純な集計関数は状態を維持せず、加算的でもありません。この関数は、グループ内の各イベントを繰り返 して集計します。集計ウィンドウには、すべてのグループのすべての 入力イベントのコピーを保持する必要があ ります。
次のコードは、これらの基本的な手順を実行します。
1 入力と出力の種類を調べ、互換性を確認してください。
2 指定された出力種類の戻り変数を初期化します。
3 グループ内のすべてのイベントをループし 、集計関数を実行します。
4 計算上の
ERROR
をチェックし、ERRORまたは結果を返します。// a non-additive summation function //
// vgs is the groupstate object passed as a (void *) pointer // fid is the filed ID in internal field order of the field on // which we sum.
dfESPdatavarPtr uSum_nadd(void *vgs, dfESPexpEngine::exp_sym_value_t *fid) { dfESPdatavar *rdv;
// placeholder for return value
dfESPgroupstate *gs = (dfESPgroupstate *)vgs;
// the passed groupstate cast back to dfESPgroupstate object.
// get the 1) aggregate schema (output schema) // and 2) the schema of input events
//
dfESPschema *aSchema = gs->getAggregateSchema();
dfESPschema *iSchema = gs->getInputSchema();
// get the type of 1) the field we are computing in the aggregate schema and // 2) the input field we are summing.
//
dfESPdatavar::dfESPdatatype aType = aSchema->getTypeEO(gs->getOperField());
bool te=false;
int64_t fID = exp_param_getI64(fid, te);
if (te) {
cerr << "could not obtain the integer field offset (field ID)" << endl;
rdv = new dfESPdatavar(aType); rdv->null();
return rdv;
}
dfESPdatavar::dfESPdatatype iType = iSchema->getTypeIO(fID);
dvn_error_t retCode = dvn_noError;
// return code for using the datavar numerics package.
// If the input fields or the output field is non-numeric, // flag an error.
//
if ( (!isNumeric(aType)) || (!isNumeric(iType)) ) {
cerr << "summation must work on numeric input, produce numeric output."
<< endl;
return NULL;
}
// in the ESP type system, INT32 < INT64 < DOUBLE < DECSECT.
// This checks compatibility. The output type must be greater // equal the input type. i.e. we cannot sum a column of int64 // and puit them into an int32 variable.
//
if (iType > aType) {
cerr << "output type is not precise enough for input type" << endl;
return NULL;
}
dfESPeventPtr nev = gs->getNewEvent();
dfESPeventPtr oev = gs->getOldEvent();
// create the datavar to return, of the output type and set to zero.
//
rdv = new dfESPdatavar(aType); // NULL by default.
rdv->makeZero();
dfESPeventPtr gEv = gs->getFirst(); // get the first event in the group.
dfESPdatavar iNdv(iType); // a place to hold the input variable.
while (gEv) { // iterarate until no more events.
gEv->copyByIntID(fID, &iNdv); // extract value from record into iNdv;
if (!iNdv.isNull()) { // input not null
if ((retCode = dv_add(rdv, rdv, &iNdv)) != dvn_noError) break; // rdv = add(rdv, iNdv)
}
gEv = gs->getNext(); // get the first event in the group.
}
if (retCode != dvn_noError ) { // if any of our arithmitic fails.
rdv->null(); // return a null value.
cerr << "uSum() got an arithmetic error in summing up values" << endl;
}
return rdv;
加算的集計関数の作成
以前のフィールド状態と新規作成フィールド値に基づいて計算する集計関数は、加算集計関数と呼ばれます。こ れらの関数は、集計関数よりも計算上の利点があります。
加算的な集計関数は、2つの理由で複雑になる可能性があります。
n 現在の状態(たとえば、最後に計算された状態)を調べる必要があります。
n 適切な調整を行うために、受信イベントの種類を評価する必要があります。
グループのフィールドの合計の最終値の状態を保持しているとします。新規作成イベントが到着すると、受信イ ベントが挿入、削除、または更新のいずれであるかを状態ベースで条件付きで調整できます。挿入イベントの場
合は、単に新規作成値で状態を増やします。削除の場合は、削除した値で状態を減らします。更新の場合は、そ れぞれ新規作成値と古い値で増減します。現在、この関数はすべてのグループ 値をループする必要はありませ ん。以前の状態とそのグループに影響を与える最新のイベントに基づいて新規作成合計を判断できます。
次のコードは、これらの基本的な手順を実行します。
1 入力と出力の種類を調べ、互換性を確認してください。
2 指定された出力種類の戻り変数を初期化します。
3 その関数が以前に呼び出されたかどうかを判定します。つまり、以前の状態値の有無です。
n そうであれば、それを検索して使用してください。
n そうでない場合は、到着する値で状態を設定できるように、到着する挿入物で新規作成グループを作成し ます。
4 演算コードをオンにして、状態値を調整します。
5 計算上の
ERROR
をチェックし、エラー値または状態値を結果として返します。// an additive summation function //
// vgs is the groupstate object passed as a (void *) pointer // fid is the filed ID in internal field order of the field on // which we sum.
dfESPdatavarPtr uSum_add(void *vgs, dfESPexpEngine::exp_sym_value_t *fid) { dfESPdatavar *rdv;
// placeholder for return value
dfESPgroupstate *gs = (dfESPgroupstate *)vgs;
// the passed groupstate cast back to dfESPgroupstate object.
// get the 1) aggregate schema (output schema) // and 2) the schema of input events
//
dfESPschema *aSchema = gs->getAggregateSchema();
dfESPschema *iSchema = gs->getInputSchema();
// get the type of 1) the field we are computing in the aggregate schema and // 2) the input field we are summing.
//
dfESPdatavar::dfESPdatatype aType = aSchema->getTypeEO(gs->getOperField());
bool te=false;
int64_t fID = exp_param_getI64(fid, te);
if (te) {
cerr << "could not obtain the integer field offset (field ID)" << endl;
rdv = new dfESPdatavar(aType); rdv->null();
return rdv;
}
dfESPdatavar::dfESPdatatype iType = iSchema->getTypeIO(fID);
dvn_error_t retCode = dvn_noError;
// return code for using the datavar numerics package.
// If the input fields or the output field is non-numeric, // flag an error.
//
if ( (!isNumeric(aType)) || (!isNumeric(iType)) ) {
cerr << "summation must work on numeric input, produce numeric output."
<< endl;
return NULL;
}
// in the ESP type system, INT32 < INT64 < DOUBLE < DECSECT.
// This checks compatibility. The output type must be greater // equal the input type. i.e. we cannot sum a column of int64 // and puit them into an int32 variable.
//
if (iType > aType) {
cerr << "output type is not precise enough for input type" << endl;
return NULL;
}
// fetch the input event from the groupstate object (nev) // and, in the case of an update, the old event that // is being updated (oev)
//
dfESPeventPtr nev = gs->getNewEvent();
dfESPeventPtr oev = gs->getOldEvent();
// Get the new value out of the input record //
dfESPdatavar iNdv(iType);
// a place to hold the input variable.
dfESPdatavar iOdv(iType);
// a place to hold the input variable (old in upd case).
nev->copyByIntID(fID, iNdv);
// extract input value (no copy) to it (from new record) // Get the old value out of the input record (update) //
if (oev) {
oev->copyByIntID(fID, iOdv);
// extract input value to it (old record) }
// Note: getStateVector() returns a reference to the state vector for // the field we are computing inside the group state object.
//
dfESPptrVect<dfESPdatavarPtr> &state = gs->getStateVector();
// create the datavar to return, of the output type and set to zero.
//
rdv = new dfESPdatavar(aType); // NULL by default.
rdv->makeZero();
// If the state has never been set, we set it and return.
//
if (state.empty()) {
dv_assign(rdv, &iNdv);
// result = input
state.push_back(new dfESPdatavar(rdv));
// make a copy and push as state return rdv;
}
// at this point we have a state,
// so lets see how we should adjust it based on opcode.
//
dfESPeventcodes::dfESPeventopcodes opCode = nev->getOpcode();
bool badOpcode = false;
int c = 0;
switch (opCode) {
case dfESPeventcodes::eo_INSERT:
if (!iNdv.isNull())
retCode = dv_add(state[0], state[0], &iNdv);
break;
case dfESPeventcodes::eo_DELETE:
if (!iNdv.isNull())
retCode = dv_subtract(state[0], state[0], &iNdv);
break;
case dfESPeventcodes::eo_UPDATEBLOCK:
retCode = dv_compare(c, &iNdv, &iOdv);
if (retCode != dvn_noError) break;
if (c == 0) // the field value did not change.
break;
if (!iNdv.isNull()) // add in the update value
retCode = dv_add(state[0], state[0], &iNdv);
if (retCode != dvn_noError) break;
if (!iOdv.isNull()) // subtract out the old value
retCode = dv_subtract(state[0], state[0], &iOdv);
break;
default:
cerr << "got a bad opcode when running uSum_add()" << endl;
badOpcode = true;
}
if ( badOpcode || (retCode != dvn_noError) ) { rdv->null();
// return a null value.
cerr << "uSum() got an arithmetic error summing up values" << endl;
} else
dv_assign(rdv, state[0]);
// return the adjusted state value return rdv;
}
Sum()集計関数を使用してグループを反復処理し、新規作成グループが変更されたときに新しい合計を計算する
ことができます。新規作成イベントが挿入、更新、または削除である場合、dfESPdatavarオブジェクトのdfESPgroupstate
にSum()を保持し、そのオブジェクトを入力値で増分または減分すると、より高速な結果が得
られます。この関数は、このフィールド状態を調整して最新の状態にし、グループの別の変更が発生したときに 再び使用することができます。
計算ウィンドウの作成
計算ウィンドウの概要
計算ウィンドウは、入力イベントストリームフィールドの計算操作を通じて入力イベントの出力イベントへの
1
対1
変換を可能にします。計算ウィンドウを使用して、あるイベントの入力フィールドを新しいイベントに投影 し、計算結果のフィールドを使用して新規作成イベントを補強することができます。キーフィールドのセットは計算ウィンドウ内で変更できますが、この関数は慎重に使用してください。計算ウィ ンドウ内でキーフィールドを変更する場合、新規作成キーセットは入力ストリームのキーセットと演算コード互 換でなければなりません。つまり、入力イベントのキーの挿入、更新、および削除は、新規作成キーセットの挿 入、更新、および削除と同等でなければなりません。
計算関数の使用
計算ウィンドウに入るイベントは、計算ウィンドウのキーフィールドに基づいてグループに配置されます。関数 または式は各グループで実行され、計算ウィンドウの各非キーフィールドを計算します。
計算ウィンドウは、式、ユーザー定義関数、またはプラグイン関数を使用して入力ストリームの計算を実行しま す。計算ウィンドウの出力フィールドは、別のウィンドウまたはサブスクライブコネクタにプッシュすることが できます。
ユーザー定義関数は、window-computeの冒頭にあるudfsおよびexpr-initializeエレメントのudfで指定さ れます。
登録されたプラグイン関数は、window-computeのoutputエレメント内のfield-plug XML言語エレメント で指定されます。これらの関数は、共有ライブラリ(DFESP_HOMEディレクトリにあるlibmethod.soや libmethod.dllなど)から供給されます。
カウンタウィンドウの作成
カウンタウィンドウを使用すると、モデルを通過するイベントの数と、処理されているレートを確認できます。
カウンタウィンドウを作成する
XML
エレメントは次のとおりです。<window-counter name='name' count-interval='period' clear-interval='cperiod'/>
フィールド 説明
name
ウィンドウの名前。count‑interval
(オプション)'[value] [unit]'
で指定された現在のイベント処理レートを生成する時間。clear‑interval
(オプション) すべてのカウンタデータが0にリセットされる、'[value] [unit]'
で指定された非ア クティブ期間。カウンタウィンドウのスキーマは設定できません。それは次のようにハードコードされています。
"input*:string,totalCount:int64,totalSeconds:double,totalRate:double,intervalCount:int64,intervalSeconds:
double,intervalRate:double"
inputの値は、イベントをカウンタウィンドウに送信したウィンドウの名前です。
生成されるイベントの演算コードは、カウンタウィンドウのインデックスに基づいています。インデックスが
pi_EMPTY
の場合、演算コードは挿入です。他のインデックス値の場合、演算コードはアップサートです。count‑interval
を指定すると、カウンタウィンドウはその間隔で定期的にパフォーマンス統計をレポートします。イベントの生成は、イベントの到着またはハートビートを受信するウィンドウによって駆動されます。ウィ ンドウは、値を報告してイベントを生成する時間かどうかをチェックします。このイベントには、全体的な値と 間隔値が含まれます。
<window-counter name='counter' count-interval='2 seconds' clear-interval='30 seconds'/>
<event opcode='upsert' window='trades/trades/counter'>
<value name='input'>trades</value>
<value name='intervalCount'>288215</value>
<value name='intervalRate'>144108</value>
<value name='intervalSeconds'>2</value>
<value name='totalCount'>794312</value>
<value name='totalRate'>132385</value>
<value name='totalSeconds'>6</value>
</event>
count‑interval
を指定しないと、ウィンドウがハートビートを受信するたびにパフォーマンス番号のイベントが生成されます。このイベントには、全体的な値のみが含まれます。
<window-counter name='counter'/>
<event opcode='upsert' window='trades/trades/counter'>
<value name='input'>trades</value>
<value name='totalCount'>7815189</value>
<value name='totalRate'>132461</value>
<value name='totalSeconds'>59</value>
</event>
カウンタウィンドウを使用するには、カウンターウィンドウをターゲットとしてエッジを追加し、モニターする ウィンドウをソースとして追加します。複数のウィンドウを同じカウンタウィンドウに接続することができま す。Streamviewerは、カウンタウィンドウにサブスクライブして結果を表示できます。あるいは、フォーマッ トされたイベントを標準出力に出力する<contquery>エレメントの
TRACE
属性にカウンタウィンドウを追加す ることもできます。フィルタウィンドウの作成
フィルタウィンドウは、登録されたブールフィルタ関数または式を使用して、フィルタウィンドウにどのような 入力イベントを許可するかを決定します。これらの関数と式はフィルタ条件と呼ばれます。
フィルタウィンドウで使用できるフィルタ条件には、式、ユーザー定義関数(グローバル関数)、および登録され たプラグイン関数が含まれます。
使用可能なフィルタ条件の詳細については、次を参照してください“式の概要”。
関数ウィンドウの作成
関数ウィンドウの概要
機能ウィンドウでは、さまざまな種類の関数を使用してイベントデータを操作または変換できます。スキーマを 定義し、次に正規式、XML、JSONなどの関数とサポートエンティティを含む機能コンテキストを定義します。
イベントが機能ウィンドウに入ると、そのウィンドウはそのスキーマの各フィールドに対応する名前の関数を探 します。関数が存在する場合、関数が実行され、結果の値が出力イベントに入力されます。フィールドに関数が 指定されておらず、同じ名前のフィールドが入力スキーマに存在する場合、入力値は出力イベントに直接コピー されます。
XML
エレメント<generate>を使用して、入力イベントからイベントを生成するかどうかを判断するために実行 する関数を指定できます。<event‑loop>エレメントを使用して、単一の入力イベントから複数の出力イベントを生成できます。ある種類の
データを作成し、作成したデータから任意の数のエンティティを取得する関数を指定できます。これらのエンテ ィティごとに、そのイベントループ固有の機能コンテキストを使用してイベントを生成できます。関数ウィンドウで関数を定義するためのサポート機能の完全なリファレンスについては、次を参照してくださ い“機能ウィンドウと通知ウィンドウのサポート機能” (SAS Event Stream Processing: プログラミングリファレン ス)。
event-loops の使用
event-loops
を使用すると、単一の入力イベントから任意の数のイベントを生成できます。任意の数のevent-
loops
を指定できます。各ループは、特定の種類のデータを処理します。各入力イベントについて、機能ウィンドウは各イベントループエントリに対して次のことを行います。
1 関数または参照を使用して、ループへの入力として使用されるデータを生成します。たとえば、
event‑loop‑xml
ループでは、use‑xmlエレメントを使用して有効なXML
を生成します。このコンテンツは、関数またはウィンドウの
function-context
内のプロパティへの参照です。2
0
以上のエンティティを取得するために、XPATHやJSON
などの適切な式をデータに適用します。3 これらのエンティティごとに、データ属性で指定されたデータ項目をエンティティの文字列値に設定します。
次に、function-context内の関数が実行され、イベントが生成されます。ウィンドウの機能コンテキスト内 のプロパティまたはイベント値は、ループの関数コンテキストからアクセス可能です。また、データ属性で 指定された変数は '$'表記でアクセスできます。
機能コンテキストの理解と使用
機能コンテキストの概要
機能コンテキストでは、機能ウィンドウ内で関数を定義できます。正規式、
XML
およびXPATH、 JSON
などの機 能を使用して、さまざまな種類の複雑な入力から使用可能な出力にデータを変換できます。使用できる関数の種類
機能コンテキスト内では、次の
2
種類の関数を使用できます。n 一般的な関数
n イベントストリーム処理に固有の関数
$[name of field]の'$'表記を使用して、入力イベントまたは出力イベントのいずれかでイベントフィールドを参
照できます。機能コンテキストでの関数の使用に関連するデータマッピングは次のとおりです。
string ESP_UTF8STR
float ESP_DOUBLE
long ESP_INT64
integer ESP_INT32
Boolean ESP_INT32
たとえば、入力イベントに
name
フィールドがあり、出力イベントにoccupation
フィールドを生成するとしま す。ifNext関数とequals関数を使用して、次のように関数をコーディングすることができます。<function name='occupation'>
ifNext (
equals($name,'larry'),'plumber', equals($name,'moe'),'electrician', equals($name,'curly'),'carpenter' )
</function>
また、出力イベントのフィールドを参照することもできます。この例を続けると、ifNextとequalsのサポート 関数を使用して、occupation値に応じて
hourlyWage
フィールドを出力イベントに追加することもできます。<function name='hourlyWage'>
ifNext (
equals($occupation,'plumber'),85.0, equals($occupation','electrician'),110.0, equals($occupation,'carpenter'),60.0 )
</function>
注: 関数を定義する場合は、フィールドの順序に注意することが重要です。関数が出力イベントフィールドを参 照する場合、参照フィールドの前にそのフィールドを計算する必要があります。
式の使用
<expressions>エレメントを使用して、1
度コンパイルされたPOSIX
正規式を指定します。<expressions>
<expression name='expname'>[posix_regular_expression]</expression>
...
</expressions>
式を指定した後、次の表記法とrgxサポート関数を使用して関数内から式を参照できます。
<function name='myData'>rgx(#expname,$inputField,1)</function>
注:
POSIX
正規式は、IEEEで指定された標準に準拠していなければなりません。URI
を含むデータフィールドを取得していて、そのURI
からプロトコルを抽出するとします。<functionname='protocol'>rgx('(.*):',$uri,1)</function>を使用すると、関数が実行されるたびに正規式がコンパイルされ
ます。ただし、次のコードを使用する場合<expressions>
<expression name='getProtocol'>(.*):</expression>
</expressions>
<function name='protocol'>rgx(#getProtocol,$uri,1)</function>
式は
1
回コンパイルされ、関数が実行されるたびに使用されます。プロパティの指定
プロパティは’#’表記法#[property‑type]を使用して関数内から参照されるという点で式と似ています。
5
種類のプロパティがあります。n
map
は、名前による値検索に使用される名前と値のペアのマップを生成する関数を実行します。n
set
は、値ルックアップに使用する一連の文字列を生成する関数を実行します。n
XML
は、XPATHクエリに使用できるXML
オブジェクトを生成する関数を実行します。n
JSON
は、JSON検索に使用できるJSON
オブジェクトを生成する関数を実行します。n
string
は関数内で一般的に使用される文字列を生成する関数を実行します。各プロパティは関数を使用して生成されます。これらの関数は、
XML
で前に定義されたプロパティを参照できま す。ここでは、プロパティの各種類をコーディングする方法を示します。
プロパティの種類 説明
<property‑map name='name' outer='outdelim'
inner='indelim'>[code]</property‑map>
nname-プロパティの名前
n
outer-データの解析に使用する外部区切り文
字
n
inner-データの解析に使用する内部区切り文字
n
code-名前値マップに解析されるデータを生成
するために実行する関数 たとえば、
firstname=joe;lastname=smith;occupation=sof tware
のような入力フィールドdata
が存在するとし ます。次のproperty-mapを作成できます。
<property‑map name='myMap' outer=';' inner='='>$data</property‑map>
<property‑xml name='name'>[code]</property‑xml>
nname-プロパティの名前
n
code-有効な XML
を生成するために実行する関数
<property‑json name='name'>[code]</property‑json>
nname-プロパティの名前
n
code-有効な JSON
を生成するために実行する 関数<property‑string name='name'>[code]</
property‑string>
nname-プロパティの名前
n