2017-05-17 4 views
0

Disons que je veux effectuer un traitement sur une table (telle que sample Github commits) qui a une structure imbriquée utilisant un JavaScript UDF. Je peux vouloir changer les champs que je regarde dans l'UDF pendant que je répète son implémentation, ainsi je décide juste de passer des rangées entières de la table à lui. Mon UDF finit par regarder quelque chose comme ceci:Comment puis-je passer une ligne de ma table à une UDF sans spécifier le type complet?

#standardSQL 
CREATE TEMP FUNCTION GetCommitStats(
    input STRUCT<commit STRING, tree STRING, parent ARRAY<STRING>, 
       author STRUCT<name STRING, email STRING, ...>>) 
    RETURNS STRUCT< 
    parent ARRAY<STRING>, 
    author_name STRING, 
    diff_count INT64> 
    LANGUAGE js AS """ 
[UDF content here] 
"""; 

J'appelle la fonction d'une requête telle que:

SELECT GetCommitStats(t).* 
FROM `bigquery-public-data.github_repos.sample_commits` AS t; 

La partie la plus lourde de la déclaration UDF est le struct d'entrée, depuis que je suis pour inclure tous les champs imbriqués et leurs types. Y a-t-il une meilleure manière de faire cela?

Répondre

2

Vous pouvez utiliser TO_JSON_STRING pour convertir des structures et des tableaux arbitraires en JSON, puis l'analyser dans un objet à des fins de traitement ultérieur. Par exemple,

#standardSQL 
CREATE TEMP FUNCTION GetCommitStats(json_str STRING) 
    RETURNS STRUCT< 
    parent ARRAY<STRING>, 
    author_name STRING, 
    diff_count INT64> 
    LANGUAGE js AS """ 
var row = JSON.parse(json_str); 
var result = new Object(); 
result['parent'] = row.parent; 
result['author_name'] = row.author.name; 
result['diff_count'] = row.difference.length; 
return result; 
"""; 

SELECT GetCommitStats(TO_JSON_STRING(t)).* 
FROM `bigquery-public-data.github_repos.sample_commits` AS t; 

Si vous voulez réduire le nombre de colonnes qui sont scannés, vous pouvez passer un struct des colonnes pertinentes à TO_JSON_STRING place:

#standardSQL 
CREATE TEMP FUNCTION GetCommitStats(json_str STRING) 
    RETURNS STRUCT< 
    parent ARRAY<STRING>, 
    author_name STRING, 
    diff_count INT64> 
    LANGUAGE js AS """ 
var row = JSON.parse(json_str); 
var result = new Object(); 
result['parent'] = row.parent; 
result['author_name'] = row.author.name; 
result['diff_count'] = row.difference.length; 
return result; 
"""; 

SELECT 
    GetCommitStats(TO_JSON_STRING(
    STRUCT(parent, author, difference) 
)).* 
FROM `bigquery-public-data.github_repos.sample_commits`; 
+1

Comment avez-vous découvert tout ce qui informations précieuses sans documentation officielle? –

+0

Procès et erreur bien sûr :) –