2017-01-17 6 views
1

標準のSQLを使用してユーザー定義関数にSTRUCTSのARRAYを渡す方法を教えてください。まず標準BigQueryのユーザー定義関数にSTRUCTのARRAYを渡すSQL

、コンテキストのビット:

表スキーマ:

id STRING 
customer STRING 
request STRUCT< 
    headers STRING 
    body STRING 
    url STRING 
> 
response STRUCT< 
    size INT64 
    body STRING 
> 
outgoing ARRAY< 
    STRUCT< 
    request STRUCT< 
     url STRING, 
     body STRING, 
     headers STRING 
    >, 
    response STRUCT< 
     size INT64, 
     body STRING 
    > 
    > 
> 

ユーザー定義関数:私の問題については

CREATE TEMPORARY FUNCTION extractDetailed(
    customer STRING, 
    request STRUCT< 
    headers STRING, 
    body STRING 
    >, 
    outgoing ARRAY< 
    STRUCT< 
     request STRUCT<url STRING>, 
     response STRUCT<body STRING> 
    > 
    > 
) 
RETURNS STRING 
LANGUAGE js AS """ 

"""; 

SELECT extractDetailed(customer, STRUCT(request.headers, request.body), outgoing) 
FROM request_logs 

:私はできませんoutgoing ARRAYの一部を選択し、それをユーザー定義の関数に渡す方法を理解しているようです配列としての配列。

が効果的に、私は次のユーザー定義関数の呼び出しをシミュレートしようとしている:

extractDetailed(
    "customer id", 
    { "headers": "", "body": "" }, 
    [ 
    { 
     "request": { "url": "" }, 
     "response": { "body": "" } 
    }, 
    { 
     "request": { "url": "" }, 
     "response": { "body": "" } 
    } 
    ] 
); 

私は最近、それをアンロックsome documentation that might helpに出くわしてきた、私はちょうどそれが収まるようにする方法を見つけ出すように見えることはできません。私は本当にこれに苦しんでおり、それを解決する助けに感謝します。

答えて

2

下記を試してください。それはあなたの配列から必要な個展に出せるを解析し、それはあなたが元の配列から抽出する部分をラップすることができ、

CREATE TEMPORARY FUNCTION extractDetailed(
customer STRING, 
request STRUCT<headers STRING, body STRING>, 
outgoing ARRAY<STRUCT<request STRUCT<url STRING>, response STRUCT<body STRING>>> 
) 
RETURNS STRING 
LANGUAGE js AS """ 

"""; 

SELECT 
    extractDetailed(
    customer, 
    STRUCT(request.headers, request.body), 
    ARRAY(
     SELECT STRUCT<request STRUCT<url STRING>,response STRUCT<body STRING>> 
      (STRUCT(request.url), STRUCT(response.body)) 
     FROM UNNEST(outgoing) 
    ) 
) AS details 
FROM request_logs 

は、クエリの上に「最適化」をさらに、それは、よりポータブルにするためにsugnature一致するように機能するために渡す前に、新しい配列に戻ってそれらを置きます別のSQL UDFに新しい配列へ

CREATE TEMPORARY FUNCTION extractParts (
    outgoing ARRAY<STRUCT<request STRUCT<url STRING, body STRING, headers STRING>, 
         response STRUCT<size INT64, body STRING>>> 
) 
RETURNS ARRAY<STRUCT<request STRUCT<url STRING>, response STRUCT<body STRING>>> 
AS ((
    SELECT ARRAY(
     SELECT STRUCT<request STRUCT<url STRING>,response STRUCT<body STRING>> 
      (struct(request.url), struct(response.body)) 
     FROM UNNEST(outgoing) 
    ) 
)); 

CREATE TEMPORARY FUNCTION extractDetailed(
    customer STRING, 
    request STRUCT<headers STRING, body STRING>, 
    outgoing ARRAY<STRUCT<request STRUCT<url STRING>, response STRUCT<body STRING>>> 
) 
RETURNS STRING 
LANGUAGE js AS """ 
    return outgoing.length; 
"""; 

SELECT 
    extractDetailed(
    customer, 
    STRUCT(request.headers, request.body), 
    extractParts(outgoing) 
) as details 
FROM request_logs 
+0

したがって、パフォーマンスの観点から、2つの間に違いはありますか? 2つのUDFを持っていることについての私の最初の考えは、それがわずかな減速を引き起こすことである。しかし、私はそれが移植性とパフォーマンスのトレードオフかもしれないと思います。 – garbetjie

+0

私の経験からSQL UDFは遅さに追加されていません。 JS UDFは可能性があります。だから、私は上記の2つが同じことをしなければならないと感じています –

+0

@garbetjie - 私の答えがあなたの問題を解決するのを助け、あなたがそれを受け入れるなら - 投票してください。 http://meter.stackexchange.com/questions/5234/how-does-accepting-an-answer-work#5235のhttp://stackoverflow.com/help/someone-answersおよびUpvoteセクションをご覧ください。 –

関連する問題