Funzioni di aggregazione definite dall'utente
Questo documento descrive come creare, chiamare ed eliminare le funzioni di aggregazione definite dall'utente (UDAF) in BigQuery.
Una UDAF consente di creare una funzione di aggregazione utilizzando un'espressione che contiene codice. Una UDAF accetta colonne di input, esegue un calcolo su un gruppo di righe alla volta e poi restituisce il risultato di questo calcolo come un singolo valore.
Creare una UDAF SQL
Questa sezione descrive i vari modi in cui puoi creare una UDAF SQL permanente o temporanea in BigQuery.
Creare una UDAF SQL permanente
Puoi creare una UDAF SQL permanente, il che significa che puoi riutilizzare la UDAF in più query. Le UDAF permanenti sono sicure da chiamare quando vengono condivise tra i proprietari. Le UDAF non possono modificare i dati, comunicare con sistemi esterni o inviare log a Google Cloud Observability o applicazioni simili.
Per creare una UDAF permanente, utilizza l'istruzione
CREATE AGGREGATE FUNCTION senza la parola chiave TEMP o TEMPORARY. Devi includere il set di dati nel percorso della funzione.
Ad esempio, la seguente query crea una UDAF permanente denominata ScaledAverage:
CREATE AGGREGATE FUNCTION myproject.mydataset.ScaledAverage( dividend FLOAT64, divisor FLOAT64) RETURNS FLOAT64 AS ( AVG(dividend / divisor) );
Creare una UDAF SQL temporanea
Puoi creare una UDAF SQL temporanea, il che significa che la UDAF esiste solo nell'ambito di una singola query, script, sessione o procedura.
Per creare una UDAF temporanea, utilizza l'
CREATE AGGREGATE FUNCTION istruzione con la parola chiave TEMP
o TEMPORARY.
Ad esempio, la seguente query crea una UDAF temporanea denominata ScaledAverage:
CREATE TEMP AGGREGATE FUNCTION ScaledAverage( dividend FLOAT64, divisor FLOAT64) RETURNS FLOAT64 AS ( AVG(dividend / divisor) );
Utilizzare parametri di aggregazione e non di aggregazione
Puoi creare una UDAF SQL con parametri di aggregazione e non di aggregazione.
Le UDAF in genere aggregano i parametri della funzione in tutte le righe di un
gruppo.
Tuttavia, puoi specificare un parametro della funzione come non di aggregazione con la parola chiave NOT AGGREGATE.
Un parametro della funzione non di aggregazione è un parametro della funzione scalare con un valore costante per tutte le righe di un gruppo. Un parametro della funzione non di aggregazione valido deve essere un valore letterale. All'interno della definizione della UDAF, i parametri della funzione di aggregazione possono essere visualizzati solo come argomenti della funzione per le chiamate di funzione di aggregazione. I riferimenti ai parametri della funzione non di aggregazione possono essere visualizzati ovunque nella definizione della UDAF.
Ad esempio, la seguente funzione contiene un parametro di aggregazione denominato dividend e un parametro non di aggregazione denominato divisor:
-- Create the function. CREATE TEMP AGGREGATE FUNCTION ScaledSum( dividend FLOAT64, divisor FLOAT64 NOT AGGREGATE) RETURNS FLOAT64 AS ( SUM(dividend) / divisor );
Utilizzare il progetto predefinito nel corpo della funzione
Nel corpo di una UDAF SQL, tutti i riferimenti alle entità BigQuery, come tabelle o viste, devono includere l'ID progetto, a meno che l'entità non si trovi nello stesso progetto che contiene la UDAF.
Ad esempio, considera la seguente istruzione:
CREATE AGGREGATE FUNCTION project1.dataset_a.ScaledAverage( dividend FLOAT64, divisor FLOAT64) RETURNS FLOAT64 AS ( ( SELECT AVG(dividend / divisor) FROM dataset_a.my_table ) );
Se esegui l'istruzione precedente nel progetto project1, l'istruzione ha esito positivo perché my_table esiste in project1. Tuttavia, se esegui l'istruzione precedente da un progetto diverso, l'istruzione non riesce.
Per correggere l'errore, includi l'ID progetto nel riferimento alla tabella:
CREATE AGGREGATE FUNCTION project1.dataset_a.ScaledAverage( dividend FLOAT64, divisor FLOAT64) RETURNS FLOAT64 AS ( ( SELECT AVG(dividend / divisor) FROM project1.dataset_a.my_table ) );
Puoi anche fare riferimento a un'entità in un progetto o set di dati diverso da quello in cui crei la funzione:
CREATE AGGREGATE FUNCTION project1.dataset_a.ScaledAverage( dividend FLOAT64, divisor FLOAT64) RETURNS FLOAT64 AS ( ( SELECT AVG(dividend / divisor) FROM project2.dataset_c.my_table ) );
Creare una UDAF JavaScript
Questa sezione descrive i vari modi in cui puoi creare una UDAF JavaScript in BigQuery. Quando crei una UDAF JavaScript, devi rispettare alcune regole:
Il corpo della UDAF JavaScript deve essere un valore letterale stringa tra virgolette che rappresenta il codice JavaScript. Per scoprire di più sui diversi tipi di valori letterali stringa tra virgolette che puoi utilizzare, consulta Formati per valori letterali tra virgolette.
Sono consentite solo determinate codifiche dei tipi. Per saperne di più, consulta Codifiche dei tipi SQL consentite in una UDAF JavaScript.
Il corpo della funzione JavaScript deve includere quattro funzioni JavaScript che inizializzano, aggregano, uniscono e finalizzano i risultati per la UDAF JavaScript (
initialState,aggregate,merge, efinalize). Per saperne di più, consulta Funzioni di aggregazione JavaScript obbligatorie.Qualsiasi valore restituito dalla funzione
initialStateo lasciato nell'argomentostatedopo la chiamata della funzioneaggregateomergedeve essere serializzabile. Se vuoi lavorare con dati di aggregazione non serializzabili, come campi di funzioni o simboli, devi utilizzare le funzioniserializeedeserializeincluse. Per saperne di più, consulta Serializzare e deserializzare i dati in una UDAF JavaScript.
Creare una UDAF JavaScript permanente
Puoi creare una UDAF JavaScript permanente, il che significa che puoi riutilizzare la UDAF in più query. Le UDAF permanenti sono sicure da chiamare quando vengono condivise tra i proprietari. Le UDAF non possono modificare i dati, comunicare con sistemi esterni o inviare log a Google Cloud Observability o applicazioni simili.
Per creare una UDAF permanente, utilizza l'istruzione
CREATE AGGREGATE FUNCTION statement senza la
TEMP o TEMPORARY parola chiave. Devi includere il set di dati nel percorso della funzione.
La seguente query crea una UDAF JavaScript permanente denominata SumPositive:
CREATE OR REPLACE AGGREGATE FUNCTION my_project.my_dataset.SumPositive(x FLOAT64) RETURNS FLOAT64 LANGUAGE js AS r''' export function initialState() { return {sum: 0} } export function aggregate(state, x) { if (x > 0) { state.sum += x; } } export function merge(state, partialState) { state.sum += partialState.sum; } export function finalize(state) { return state.sum; } '''; -- Call the JavaScript UDAF. WITH numbers AS ( SELECT * FROM UNNEST([1.0, -1.0, 3.0, -3.0, 5.0, -5.0]) AS x) SELECT my_project.my_dataset.SumPositive(x) AS sum FROM numbers; /*-----* | sum | +-----+ | 9.0 | *-----*/
Creare una UDAF JavaScript temporanea
Puoi creare una UDAF JavaScript temporanea, il che significa che la UDAF esiste solo nell'ambito di una singola query, script, sessione o procedura.
Per creare una UDAF temporanea, utilizza l'
CREATE AGGREGATE FUNCTION istruzione con la parola chiave TEMP
o TEMPORARY.
La seguente query crea una UDAF JavaScript temporanea denominata SumPositive:
CREATE TEMP AGGREGATE FUNCTION SumPositive(x FLOAT64) RETURNS FLOAT64 LANGUAGE js AS r''' export function initialState() { return {sum: 0} } export function aggregate(state, x) { if (x > 0) { state.sum += x; } } export function merge(state, partialState) { state.sum += partialState.sum; } export function finalize(state) { return state.sum; } '''; -- Call the JavaScript UDAF. WITH numbers AS ( SELECT * FROM UNNEST([1.0, -1.0, 3.0, -3.0, 5.0, -5.0]) AS x) SELECT SumPositive(x) AS sum FROM numbers; /*-----* | sum | +-----+ | 9.0 | *-----*/
Includere parametri non di aggregazione in una UDAF JavaScript
Puoi creare una UDAF JavaScript con parametri di aggregazione e non di aggregazione.
Le UDAF in genere aggregano i parametri della funzione in tutte le righe di un
gruppo.
Tuttavia, puoi specificare un parametro della funzione come non di aggregazione con la parola chiave NOT AGGREGATE.
Un parametro della funzione non di aggregazione è un parametro della funzione scalare con un valore costante per tutte le righe di un gruppo. Un parametro della funzione non di aggregazione valido deve essere un valore letterale. All'interno della definizione della UDAF, i parametri della funzione di aggregazione possono essere visualizzati solo come argomenti della funzione per le chiamate di funzione di aggregazione. I riferimenti ai parametri della funzione non di aggregazione possono essere visualizzati ovunque nella definizione della UDAF.
Nell'esempio seguente, la UDAF JavaScript contiene un parametro di aggregazione
denominato s e un parametro non di aggregazione denominato delimiter:
CREATE TEMP AGGREGATE FUNCTION JsStringAgg( s STRING, delimiter STRING NOT AGGREGATE) RETURNS STRING LANGUAGE js AS r''' export function initialState() { return {strings: []} } export function aggregate(state, s) { state.strings.push(s); } export function merge(state, partialState) { state.strings = state.strings.concat(partialState.strings); } export function finalize(state, delimiter) { return state.strings.join(delimiter); } '''; -- Call the JavaScript UDAF. WITH strings AS ( SELECT * FROM UNNEST(["aaa", "bbb", "ccc", "ddd"]) AS values) SELECT JsStringAgg(values, '.') AS result FROM strings; /*-----------------* | result | +-----------------+ | aaa.bbb.ccc.ddd | *-----------------*/
Serializzare e deserializzare i dati in una UDAF JavaScript
BigQuery deve serializzare qualsiasi oggetto restituito dalla funzione initialState o lasciato nell'argomento state dopo la chiamata della funzione aggregate o merge.
BigQuery supporta la serializzazione di un oggetto se tutti i campi sono uno dei seguenti:
- Un valore primitivo JavaScript (ad esempio:
2,"abc",null,undefined). - Un oggetto JavaScript per il quale BigQuery supporta la serializzazione di tutti i valori dei campi.
- Un array JavaScript per il quale BigQuery supporta la serializzazione di tutti gli elementi.
I seguenti valori restituiti sono serializzabili:
export function initialState() {
return {a: "", b: 3, c: null, d: {x: 23} }
}
export function initialState() {
return {value: 2.3};
}
I seguenti valori restituiti non sono serializzabili:
export function initialState() {
return {
value: function() {return 6;}
}
}
export function initialState() {
return 2.3;
}
Se vuoi lavorare con stati di aggregazione non serializzabili,
la UDAF JavaScript deve includere le funzioni serialize e deserialize.
La funzione serialize converte lo stato di aggregazione in un oggetto serializzabile
; la funzione deserialize riconverte l'oggetto serializzabile in uno stato di aggregazione.
Nell'esempio seguente, una libreria esterna calcola le somme utilizzando un'interfaccia:
export class SumAggregator { constructor() { this.sum = 0; } update(value) { this.sum += value; } getSum() { return this.sum; } }
La seguente query non viene eseguita perché l'oggetto della classe SumAggregator non è serializzabile da BigQuery a causa della presenza di funzioni all'interno della classe.
CREATE TEMP AGGREGATE FUNCTION F(x FLOAT64) RETURNS FLOAT64 LANGUAGE js AS r''' class SumAggregator { constructor() { this.sum = 0; } update(value) { this.sum += value; } getSum() { return this.sum; } } export function initialState() { return new SumAggregator(); } export function aggregate(agg, value) { agg.update(value); } export function merge(agg1, agg2) { agg1.update(agg2.getSum()); } export function finalize(agg) { return agg.getSum(); } '''; --Error: getSum is not a function SELECT F(x) AS results FROM UNNEST([1,2,3,4]) AS x;
Se aggiungi le funzioni serialize e deserialize alla query precedente, la query viene eseguita perché l'oggetto della classe SumAggregator viene convertito in un oggetto serializzabile da BigQuery e poi di nuovo in un oggetto della classe SumAggregator.
CREATE TEMP AGGREGATE FUNCTION F(x FLOAT64) RETURNS FLOAT64 LANGUAGE js AS r''' class SumAggregator { constructor() { this.sum = 0; } update(value) { this.sum += value; } getSum() { return this.sum; } } export function initialState() { return new SumAggregator(); } export function aggregate(agg, value) { agg.update(value); } export function merge(agg1, agg2) { agg1.update(agg2.getSum()); } export function finalize(agg) { return agg.getSum(); } export function serialize(agg) { return {sum: agg.getSum()}; } export function deserialize(serialized) { var agg = new SumAggregator(); agg.update(serialized.sum); return agg; } '''; SELECT F(x) AS results FROM UNNEST([1,2,3,4]) AS x; /*-----------------* | results | +-----------------+ | 10.0 | *-----------------*/
Per saperne di più sulle funzioni di serializzazione, consulta Funzioni di serializzazione JavaScript facoltative.
Includere variabili globali e funzioni personalizzate in una UDAF JavaScript
Il corpo della funzione JavaScript può includere codice JavaScript personalizzato, come variabili globali JavaScript e funzioni personalizzate.
Le variabili globali vengono eseguite quando JavaScript viene caricato in BigQuery e prima dell'esecuzione della funzione initialState.
Le variabili globali potrebbero essere utili se devi eseguire un'inizializzazione una tantum che non deve essere ripetuta per ogni gruppo di aggregazione, come nel caso delle funzioni initialState, aggregate, merge e finalize.
Non utilizzare le variabili globali per archiviare lo stato di aggregazione. Limita invece lo stato di aggregazione agli oggetti passati alle funzioni esportate. Utilizza le variabili globali solo per memorizzare nella cache le operazioni costose che non sono specifiche di alcuna operazione di aggregazione.
Nella seguente query, la funzione SumOfPrimes calcola una somma, ma nel calcolo vengono inclusi solo i numeri primi. Nel corpo della funzione JavaScript sono presenti due variabili globali, primes e maxTested, che vengono inizializzate per prime. Inoltre, esiste una funzione personalizzata denominata isPrime che verifica se un numero è primo.
CREATE TEMP AGGREGATE FUNCTION SumOfPrimes(x INT64) RETURNS INT64 LANGUAGE js AS r''' var primes = new Set([2]); var maxTested = 2; function isPrime(n) { if (primes.has(n)) { return true; } if (n <= maxTested) { return false; } for (var k = 2; k < n; ++k) { if (!isPrime(k)) { continue; } if ((n % k) == 0) { maxTested = n; return false; } } maxTested = n; primes.add(n); return true; } export function initialState() { return {sum: 0}; } export function aggregate(state, x) { x = Number(x); if (isPrime(x)) { state.sum += x; } } export function merge(state, partialState) { state.sum += partialState.sum; } export function finalize(state) { return state.sum; } '''; -- Call the JavaScript UDAF. WITH numbers AS ( SELECT * FROM UNNEST([10, 11, 13, 17, 19, 20]) AS x) SELECT SumOfPrimes(x) AS sum FROM numbers; /*-----* | sum | +-----+ | 60 | *-----*/
Includere librerie JavaScript
Puoi estendere le UDAF JavaScript con l'opzione library nella clausola OPTIONS. Questa opzione ti consente di specificare librerie di codice esterne per la UDAF JavaScript e poi di importarle con la dichiarazione import.
Nell'esempio seguente, il codice in bar.js è disponibile per qualsiasi codice nel corpo della funzione della UDAF JavaScript:
CREATE TEMP AGGREGATE FUNCTION JsAggFn(x FLOAT64) RETURNS FLOAT64 LANGUAGE js OPTIONS (library = ['gs://foo/bar.js']) AS r''' import doInterestingStuff from 'bar.js'; export function initialState() { return ... } export function aggregate(state, x) { var result = doInterestingStuff(x); ... } export function merge(state, partial_state) { ... } export function finalize(state) { return ...; } ''';
Struttura JavaScript obbligatoria
A differenza di una UDF JavaScript, in cui il corpo della funzione è JavaScript in formato libero che viene eseguito per ogni riga, il corpo della funzione per una UDAF JavaScript è un modulo JavaScript che contiene alcune funzioni esportate integrate, che vengono richiamate in varie fasi del processo di aggregazione. Alcune di queste funzioni integrate sono obbligatorie, mentre altre sono facoltative. Puoi anche aggiungere le tue funzioni JavaScript.
Funzioni di aggregazione JavaScript obbligatorie
Puoi includere le tue funzioni JavaScript, ma il corpo della funzione JavaScript deve includere le seguenti funzioni JavaScript esportabili:
initialState([nonAggregateParam]): restituisce un oggetto JavaScript che rappresenta uno stato di aggregazione in cui non sono ancora state aggregate righe.aggregate(state, aggregateParam[, ...][, nonAggregateParam]): aggrega una riga di dati, aggiornando lo stato per memorizzare il risultato dell'aggregazione. Non restituisce un valore.merge(state, partialState, [nonAggregateParam]): unisce lo stato di aggregazionepartialStatenello stato di aggregazionestate. Questa funzione viene utilizzata quando il motore aggrega in parallelo diverse sezioni di dati e deve combinare i risultati. Non restituisce un valore.finalize(finalState, [nonAggregateParam]): restituisce il risultato finale della funzione di aggregazione, dato uno stato di aggregazione finalefinalState.
Per saperne di più sulle funzioni obbligatorie, consulta Funzioni obbligatorie in una UDAF JavaScript.
Funzioni di serializzazione JavaScript facoltative
Se vuoi lavorare con stati di aggregazione non serializzabili, la
UDAF JavaScript deve fornire le funzioni serialize e deserialize.
La funzione serialize converte lo stato di aggregazione in un oggetto serializzabile da
BigQuery, mentre la funzione deserialize riconverte l'oggetto serializzabile da
BigQuery in uno stato di aggregazione.
serialize(state): restituisce un oggetto serializzabile che contiene le informazioni nello stato di aggregazione, da deserializzare tramite la funzionedeserialize.deserialize(serializedState): deserializzaserializedState(precedentemente serializzato dalla funzioneserialize) in uno stato di aggregazione che può essere passato alle funzioniserialize,aggregate,merge, ofinalize.
Per saperne di più sulle funzioni di serializzazione JavaScript integrate, consulta Funzioni di serializzazione per una UDAF JavaScript.
Per scoprire come serializzare e deserializzare i dati con una UDAF JavaScript, consulta Serializzare e deserializzare i dati in una UDAF JavaScript.
Codifiche dei tipi SQL consentite in una UDAF JavaScript
Nelle UDAF JavaScript, i seguenti tipi di dati GoogleSQL supportati rappresentano i tipi di dati JavaScript come segue:
| Tipo di dati GoogleSQL |
Tipo di dati JavaScript |
Note |
|---|---|---|
ARRAY |
Array |
Un array di array non è supportato. Per aggirare questa
limitazione, utilizza i tipi di dati
Array<Object<Array>> (JavaScript) e
ARRAY<STRUCT<ARRAY>> (GoogleSQL)
.
|
BIGNUMERIC
|
Number o String
|
Uguale a NUMERIC.
|
BOOL |
Boolean |
|
BYTES |
Uint8Array |
|
DATE |
Date |
|
FLOAT64 |
Number |
|
INT64 |
BigInt |
|
JSON |
Vari tipi |
Il tipo di dati JSON di GoogleSQL può essere convertito
in un Object, Array o altro
tipo di dati JavaScript supportato da GoogleSQL.
|
NUMERIC
|
Number o String
|
Se un valore NUMERIC può essere rappresentato esattamente come una rappresentazione in virgola mobile IEEE 754 (intervallo [-253, 253]) e non ha una parte frazionaria, viene codificato come tipo di dati Number, altrimenti viene codificato come tipo di dati String.
|
STRING |
String |
|
STRUCT |
Object |
Ogni STRUCT campo è una proprietà denominata nel
Object tipo di dati. Un campo STRUCT senza nome non è supportato.
|
TIMESTAMP |
Date |
Date contiene un campo di microsecondi con la frazione di microsecondi di TIMESTAMP.
|
Chiamare una UDAF
Questa sezione descrive i vari modi in cui puoi chiamare una UDAF permanente o temporanea dopo averla creata in BigQuery.
Chiamare una UDAF permanente
Puoi chiamare una UDAF permanente nello stesso modo in cui chiami una funzione di aggregazione integrata. Per saperne di più, consulta Chiamate di funzioni di aggregazione. Devi includere il set di dati nel percorso della funzione.
Nell'esempio seguente, la query chiama una UDAF permanente denominata WeightedAverage:
SELECT my_project.my_dataset.WeightedAverage(item, weight, 2) AS weighted_average FROM ( SELECT 1 AS item, 2.45 AS weight UNION ALL SELECT 3 AS item, 0.11 AS weight UNION ALL SELECT 5 AS item, 7.02 AS weight );
Viene generata una tabella con i seguenti risultati:
/*------------------*
| weighted_average |
+------------------+
| 4.5 |
*------------------*/
Chiamare una UDAF temporanea
Puoi chiamare una UDAF temporanea nello stesso modo in cui chiami una funzione di aggregazione integrata. Per saperne di più, consulta Chiamate di funzioni di aggregazione.
La funzione temporanea deve essere inclusa in una query con più istruzioni o procedura che contiene la chiamata di funzione UDAF.
Nell'esempio seguente, la query chiama una UDAF temporanea denominata WeightedAverage:
CREATE TEMP AGGREGATE FUNCTION WeightedAverage(...) -- Temporary UDAF function call SELECT WeightedAverage(item, weight, 2) AS weighted_average FROM ( SELECT 1 AS item, 2.45 AS weight UNION ALL SELECT 3 AS item, 0.11 AS weight UNION ALL SELECT 5 AS item, 7.02 AS weight );
Viene generata una tabella con i seguenti risultati:
/*------------------*
| weighted_average |
+------------------+
| 4.5 |
*------------------*/
Ignorare o includere righe con valori NULL
Quando una UDAF JavaScript viene chiamata con l'argomento IGNORE NULLS,
BigQuery salta automaticamente le righe per le quali qualsiasi argomento di aggregazione
restituisce NULL. Queste righe vengono escluse completamente dall'aggregazione e non vengono passate alla funzione JavaScript aggregate. Quando
RESPECT NULLS argomento viene fornito, NULL filtro viene disattivato e ogni
riga viene passata alla UDAF JavaScript, indipendentemente dai NULL valori.
Se non viene fornito l'argomento IGNORE NULLS né RESPECT NULLS, l'argomento predefinito è IGNORE NULLS.
L'esempio seguente illustra il comportamento NULL predefinito,
il comportamento IGNORE NULLS e il comportamento RESPECT NULLS:
CREATE TEMP AGGREGATE FUNCTION SumPositive(x FLOAT64) RETURNS FLOAT64 LANGUAGE js AS r''' export function initialState() { return {sum: 0} } export function aggregate(state, x) { if (x == null) { // Use 1000 instead of 0 as placeholder for null so // that NULL values passed are visible in the result. state.sum += 1000; return; } if (x > 0) { state.sum += x; } } export function merge(state, partialState) { state.sum += partialState.sum; } export function finalize(state) { return state.sum; } '''; -- Call the JavaScript UDAF. WITH numbers AS ( SELECT * FROM UNNEST([1.0, 2.0, NULL]) AS x) SELECT SumPositive(x) AS sum, SumPositive(x IGNORE NULLS) AS sum_ignore_nulls, SumPositive(x RESPECT NULLS) AS sum_respect_nulls FROM numbers; /*-----+------------------+-------------------* | sum | sum_ignore_nulls | sum_respect_nulls | +-----+------------------+-------------------+ | 3.0 | 3.0 | 1003.0 | *-----+------------------+-------------------*/
Eliminare una UDAF
Questa sezione descrive i vari modi in cui puoi eliminare una UDAF permanente o temporanea dopo averla creata in BigQuery.
Eliminare una UDAF permanente
Per eliminare una UDAF permanente, utilizza l'
DROP FUNCTION istruzione.
Devi includere il set di dati nel percorso della funzione.
Nell'esempio seguente, la query elimina una UDAF permanente denominata WeightedAverage:
DROP FUNCTION IF EXISTS my_project.my_dataset.WeightedAverage;
Eliminare una UDAF temporanea
Per eliminare una UDAF temporanea, utilizza l'
DROP FUNCTION istruzione.
Nell'esempio seguente, la query elimina una UDAF temporanea denominata WeightedAverage:
DROP FUNCTION IF EXISTS WeightedAverage;
Una UDAF temporanea scade al termine della query. Non è necessario eliminare la UDAF , a meno che tu non voglia rimuoverla in anticipo da una query con più istruzioni o procedura.
Elencare le UDAF
Le UDAF sono un tipo di routine. Per elencare tutte le routine in un set di dati, consulta Elencare le routine.
Suggerimenti sulle prestazioni
Se vuoi migliorare le prestazioni delle query, valuta quanto segue:
Pre-filtra l'input. L'elaborazione dei dati in JavaScript è più costosa rispetto a SQL, quindi è preferibile filtrare l'input il più possibile in SQL.
La seguente query è meno efficiente perché filtra l'input utilizzando
x > 0nella chiamata UDAF:SELECT JsFunc(x) FROM t;La seguente query è più efficiente perché pre-filtra l'input utilizzando
WHERE x > 0prima della chiamata UDAF:SELECT JsFunc(x) FROM t WHERE x > 0;Se possibile, utilizza le funzioni di aggregazione integrate anziché JavaScript. La reimplementazione di una funzione di aggregazione integrata in JavaScript è più lenta rispetto alla chiamata di una funzione di aggregazione integrata che esegue la stessa operazione.
La seguente query è meno efficiente perché implementa una UDAF:
SELECT SumSquare(x) FROM t;La seguente query è più efficiente perché implementa una funzione integrata che produce gli stessi risultati della query precedente:
SELECT SUM(x*x) FROM t;Le UDAF JavaScript sono appropriate per operazioni di aggregazione più complesse, che non possono essere espresse tramite funzioni integrate.
Utilizza la memoria in modo efficiente. L'ambiente di elaborazione JavaScript ha una memoria limitata disponibile per ogni query. Le query UDAF JavaScript che accumulano troppo stato locale potrebbero non riuscire a causa dell'esaurimento della memoria. Presta particolare attenzione a ridurre al minimo le dimensioni degli oggetti di stato di aggregazione ed evita gli stati di aggregazione che accumulano un numero elevato di righe.
La seguente query non è efficiente perché la funzione
aggregateutilizza una quantità illimitata di memoria quando il numero di righe elaborate diventa elevato.export function initialState() { return {rows: []}; } export function aggregate(state, x) { state.rows.push(x); } ...Se possibile, utilizza le tabelle partizionate. Le UDAF JavaScript in genere vengono eseguite in modo più efficiente quando vengono eseguite query su una tabella partizionata rispetto a una tabella non partizionata, perché una tabella partizionata archivia i dati in molti file più piccoli rispetto a una tabella non partizionata, consentendo quindi un parallelismo maggiore.
Limitazioni
Le UDAF hanno le stesse limitazioni delle UDF. Per maggiori dettagli, consulta Limitazioni delle UDF.
Solo i valori letterali, parametri di ricerca e le variabili di script possono essere passati come argomenti non di aggregazione per una UDAF.
L'utilizzo della clausola
ORDER BYin una chiamata di funzione UDAF JavaScript non è supportato.SELECT MyUdaf(x ORDER BY y) FROM t; -- Error: ORDER BY is unsupported.
Prezzi
Le UDAF vengono fatturate utilizzando il modello di determinazione dei prezzi standard BigQuery.
Quote e limiti
Le UDAF hanno le stesse quote e gli stessi limiti delle UDF. Per informazioni sulle quote delle UDF, consulta Quote e limiti.