2

2 つのデータ ソースがあります。1 つは API 呼び出しのリストを含み、もう 1 つは関連するすべての認証イベントを含みます。Api 呼び出しごとに複数の認証イベントが存在する可能性があります。次のような認証イベントを見つけたい:
a) API 呼び出しと同じ「識別子」を含む
b) API 呼び出しから 1 秒以内に発生した
c) API に最も近い上記のフィルタリングの後に呼び出します。

foreachループで各ApiCallイベントをループし、autheventsでフィルターステートメントを使用して正しいイベントを見つけることを計画していましたが、これは可能ではないようです(PIGのネストされたFOREACHでフィルターを使用)

これを達成するための他の方法を提案できる人はいますか。それが役立つ場合は、使用しようとした Pig スクリプトを次に示します。

apiRequests = LOAD '/Documents/ApiRequests.txt' AS (api_fileName:chararray, api_requestTime:long, api_timeFromLog:chararray, api_call:chararray, api_leadString:chararray, api_xmlPayload:chararray, api_sourceIp:chararray, api_username:chararray, api_identifier:chararray);
authEvents = LOAD '/Documents/AuthEvents.txt' AS (auth_fileName:chararray, auth_requestTime:long, auth_timeFromLog:chararray, auth_call:chararray, auth_leadString:chararray, auth_xmlPayload:chararray, auth_sourceIp:chararray, auth_username:chararray, auth_identifier:chararray);
specificApiCall = FILTER apiRequests BY api_call == 'CSGetUser';                 -- Get all events for this specific call
match = foreach specificApiCall {                                                -- Now try to get the closest mathcing auth event
        filtered1 = filter authEvents by auth_identifier == api_identifier;      -- Only use auth events that have the same identifier (this will return several)
        filtered2 = filter filtered1 by (auth_requestTime-api_requestTime)<1000; -- Further refine by usings auth events within a second on the api call's tiime
        sorted = order filtered2 by auth_requestTime;                            -- Get the auth event that's closest to the api call
        limited = limit sorted 1;
        generate limited;
        };
dump match;
4

1 に答える 1

1

NestedFOREACHは、最初のリレーションをループしながら 2 番目のリレーションを操作するためのものではありません。これは、リレーションにバッグがあり、そのバッグを独自のリレーションであるかのように操作したい場合に使用します。apiRequests最初になんらかの結合またはグループ化を行って、必要なすべての情報を 1 つの関係にまとめない限り、authEvents同時に操作することはできません。

単一の承認イベントに限定する必要がない場合、タスクは概念的にJOINandでうまく機能します。FILTER

allPairs = JOIN specificApiCall BY api_identifier, authEvents BY auth_identifier;
match = FILTER allPairs BY (auth_requestTime-api_requestTime)<1000;

GROUP match BY api_identifierこれですべての情報がまとめられ、ネストされたイベントを続けて 1 つのイベントを選択することができますFOREACH

COGROUPただし、演​​算子を使用すると、これを 1 つのステップで実行できます。これはJOINクロス積を使用しない場合と似ていますが、各リレーションからグループ化されたレコードを含む 2 つのバッグが得られます。これを使用して、最も近い承認イベントを選択します。

cogrp = COGROUP specificApiCall BY api_identifier, authEvents BY auth_identifier;
singleAuth = FOREACH cogrp {
    auth_sorted = ORDER authEvents BY auth_requestTime;
    auth_1 = LIMIT auth_sorted 1;
    GENERATE FLATTEN(specificApiCall), FLATTEN(auth_1);
    };

次にFILTER、1 秒以内のものだけを残すには:

match = FILTER singleAuth BY (auth_requestTime-api_requestTime)<1000;
于 2013-06-29T21:25:38.567 に答える