Как я могу передать строку из моей таблицы в UDF без указания полного типа?
Допустим, я хочу выполнить некоторую обработку таблицы (например, образца коммитов Github), который имеет вложенную структуру с использованием JavaScript UDF. Я могу захотеть изменить поля, которые я смотрю в UDF, когда я повторяю его реализацию, поэтому я решаю просто передать ему целые строки из таблицы. Мой UDF выглядит примерно так:
#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]
""";
Затем я вызываю функцию с таким запросом, как:
SELECT GetCommitStats(t).*
FROM `bigquery-public-data.github_repos.sample_commits` AS t;
Самая громоздкая часть объявления UDF - это структура ввода, так как мне нужно включить все вложенные поля и их типы. Есть лучший способ сделать это?
1 ответ
Ты можешь использовать TO_JSON_STRING
преобразовать произвольные структуры и массивы в JSON, а затем проанализировать их внутри UDF в объект для дальнейшей обработки. Например,
#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;
Если вы хотите сократить количество сканируемых столбцов, вы можете передать структуру соответствующих столбцов в TO_JSON_STRING
вместо:
#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`;