Gerenciar tipos de dados de matriz e mapa com funções de ordem superior

Use este guia para saber como as funções de ordem superior podem processar tipos de dados complexos, como matrizes e mapas. Essas funções eliminam a necessidade de explodir a matriz, executam uma função e combinam o resultado. Funções de ordem superior são particularmente úteis para analisar ou processar conjuntos de dados e análises de séries temporais, que geralmente apresentam estruturas aninhadas complexas, arrays, mapas e casos de uso diversos.

A lista de casos de uso a seguir contém exemplos de funções de matriz e de manipulação de mapa de ordem superior.

Usar transformação para ajustar o preço total por n adjust-price-total

transform(array<T>, function<T, U>): array<U>

O trecho acima aplica uma função a cada elemento da matriz e retorna uma nova matriz de elementos transformados. Especificamente, a função transform pega uma matriz do tipo T e converte cada elemento do tipo T para o tipo U. Em seguida, retorna uma matriz de tipo U. Os tipos reais T e U dependem do uso específico da função de transformação.

transform(array<T>, function<T, Int, U>): array<U>

Esta função de transformação de matriz é semelhante ao exemplo anterior, mas há dois argumentos para a função. O segundo argumento nessa função também recebe o índice do elemento na matriz, além de ser transformado.

Exemplo

O exemplo de SQL abaixo demonstra esse caso de uso. A consulta recupera um conjunto limitado de linhas da tabela especificada, transformando a matriz productListItems multiplicando o atributo priceTotal de cada item por 73. O resultado inclui as colunas _id, productListItems e as colunas price_in_inr transformadas. A seleção é baseada em um intervalo específico de carimbo de data e hora.

SELECT _id,
       productListItems,
       Transform(productListItems, value -> value.priceTotal * 73) AS
       price_in_inr
FROM   geometrixxx_999_xdm_pqs_1batch_10k_rows
WHERE  timestamp > To_timestamp('2017-11-01 00:00:00')
       AND timestamp < To_timestamp('2017-11-02 00:00:00')
LIMIT  10;

Resultado

Os resultados para esse SQL seriam semelhantes aos vistos abaixo.

 productListItems | price_in_inr
-------------------+----------------
(8376, NULL, NULL) | 611448.0
{(Burbank Hills Jeans, NULL, NULL), (Thermomax Steel, NULL, NULL), (Bruin Point Shearling Boots, NULL, NULL), (Uintas Pro Ski Gloves, NULL, NULL), (Timberline Survival Knife, NULL, NULL), (Thermomax Steel, NULL, NULL), (Timpanogos Scarf, NULL, NULL), (Lost Prospector Beanie, NULL, NULL), (Timpanogos Scarf, NULL, NULL), (Uintas Pro Ski Gloves, NULL, NULL)} | {0.0,0.0.0.0,0,0,0,0,0,0,0,0,0,0,0,0,0.0}
(84763,NULL, NULL) | 6187699.0
(843765, NULL, NULL) | 6.1594845E7
(199684, NULL, NULL) | 1.4576932E7

(10 rows)

Existe uso para descobrir se um produto com um SKU específico existe confirm-product-exists

exists(array<T>, function<T, boolean>): boolean

No trecho acima, a função exists é aplicada a cada elemento da matriz e retorna um valor booleano. O booleano indica se há um ou mais elementos na matriz que satisfazem uma condição especificada. Nesse caso, confirma se um produto com uma SKU específica existe.

Exemplo

No exemplo SQL abaixo, a consulta busca productListItems da tabela geometrixxx_999_xdm_pqs_1batch_10k_rows e avalia se existe um elemento com uma SKU igual a 123679 na matriz productListItems. Em seguida, ele filtra os resultados com base em um intervalo específico de carimbos de data e hora e limita os resultados finais a dez linhas.

SELECT productListItems
FROM geometrixxx_999_xdm_pqs_1batch_10k_rows
WHERE EXISTS( productListItems, value -> value.sku == 123679)
AND timestamp > to_timestamp('2017-11-01 00:00:00')
AND timestamp < to_timestamp('2017-11-02 00:00:00')limit 10;

Resultado

Os resultados para esse SQL seriam semelhantes aos vistos abaixo.

productListItems
-----------------
{(123679, NULL,NULL)}
{(123679, NULL, NULL)}
{(123679, NULL, NULL), (150196, NULL, NULL)}
{(123679, NULL, NULL), (150196, NULL, NULL)}
{(123679, NULL, NULL), (150196, NULL, NULL)}
{(123679, NULL, NULL)}
{(123679, NULL, NULL)}
{(123679, NULL, NULL)}
{(123679, NULL,NULL)}
{(123679,NULL, NULL)}

(10 rows)

Use o filtro para localizar produtos nos quais o SKU > 100000 find-specific-products

filter(array<T>, function<T, boolean>): array<T>

Essa função filtra uma matriz de elementos com base em uma determinada condição que avalia cada elemento como um valor booleano. Em seguida, ele retorna uma nova matriz que inclui apenas elementos em que a condição retornou um valor verdadeiro.

Exemplo

A consulta abaixo seleciona a coluna productListItems, aplica um filtro para incluir apenas elementos com SKU maior que 100000 e restringe o conjunto de resultados a linhas em um intervalo de carimbo de data/hora específico. A matriz filtrada recebe o alias como _filter na saída.

SELECT productListItems,
    Filter(productListItems, value -> value.sku > 100000) AS _filter
FROM geometrixxx_999_xdm_pqs_1batch_10k_rows
WHERE timestamp > To_timestamp('2017-11-01 00:00:00')
AND timestamp < To_timestamp('2017-11-02 00:00:00')
LIMIT 10;

Resultado

Os resultados para esse SQL seriam semelhantes aos vistos abaixo.

productListItems | _filter
-----------------+---------
(123679, NULL, NULL) (123679, NULL, NULL)
(1346, NULL, NULL) |
(98347, NULL, NULL) |
(176015, NULL, NULL) | (176015, NULL, NULL)

(10 rows)

Use a agregação para somar os SKUs de todos os itens da lista de produtos associados a uma ID específica e dobrar o total resultante sum-specific-skus-and-double-the-resulting-total

aggregate(array<T>, A, function<A, T, A>[, function<A, R>]): R

Essa operação de agregação aplica um operador binário a um estado inicial e a todos os elementos na matriz. Também reduz vários valores a um único estado. Após essa redução, o estado final é convertido no resultado final usando uma função finish. A função finish toma o último estado obtido após aplicar o operador binário a todos os elementos de matriz e faz algo com ele para produzir o resultado final.

Exemplo

Este exemplo de consulta calcula o valor máximo de SKU da matriz productListItems dentro do intervalo de carimbo de data/hora especificado e dobra o resultado. A saída inclui a matriz productListItems original e o max_value calculado.

SELECT productListItems,
aggregate(productListItems, 0, (acc, value) ->
case
WHEN (
value.sku > acc) THEN cast(value.sku AS int)
ELSE cast(acc AS int)
END, acc -> acc * 2) AS max_value
FROM geometrixxx_999_xdm_pqs_1batch_10k_rows
WHERE timestamp > to_timestamp('2017-11-01 00:00:00')
AND timestamp < to_timestamp('2017-11-02 00:00:00')
LIMIT 50;

Resultado

Os resultados para esse SQL seriam semelhantes aos vistos abaixo.

productListItems | max_value
-----------------+---------
(123679, NULL, NULL) | 247358
(1346,NULL, NULL) | 2692
(98347, NULL, NULL) | 196694
(176015, NULL, NULL) | 352030

(10 rows)

Use zip_with para atribuir um número de sequência a todos os itens na lista de produtos assign-a-sequence-number

zip_with(array<T>, array<U>, function<T, U, R>): array<R>

Este fragmento combina os elementos de dois arrays em um único array novo. A operação é executada de forma independente em cada elemento da matriz e gera pares de valores. Se uma matriz for mais curta, valores nulos serão adicionados para corresponder ao comprimento da matriz mais longa. Isso acontece antes da função ser aplicada.

Exemplo

A consulta a seguir usa a função zip_with para criar pares de valores de duas matrizes. Ele faz isso adicionando os valores de SKU da matriz productListItems a uma sequência inteira, que foi gerada usando a função Sequence. O resultado é selecionado junto com a coluna original productListItems e é limitado com base em um intervalo de carimbo de data/hora.

SELECT productListItems,
zip_with(Sequence(1,5), Transform(productListItems, p -> p.sku), (x,y) -> struct(x, y)) AS zip_with
FROM geometrixxx_999_xdm_pqs_1batch_10k_rows
WHERE timestamp > to_timestamp('2017-11-01 00:00:00')
AND timestamp < to_timestamp('2017-11-02 00:00:00')
limit 10;

Resultado

Os resultados para esse SQL seriam semelhantes aos vistos abaixo.

productListItems     | zip_with
---------------------+---------
                     | {(1,NULL), (2,NULL), (3,NULL),(4,NULL), (5,NULL)}
(123679, NULL, NULL) | {(1,123679), (2,NULL), (3,NULL), (4,NULL), (5,NULL)}
                     | {(1,NULL), (2,NULL),(3,NULL),(4,NULL), (5,NULL)}
                     | {(1,NULL), (2,NULL), (3, NULL),(4,NULL), (5,NULL)}
(1346,NULL, NULL)    | {(1,1346), (2,NULL),(3,NULL),(4,NULL), (5,NULL)}
                     | {(1,NULL), (2,NULL), (3,NULL),(4,NULL), (5,NULL)}
(98347, NULL, NULL)  | {(1,98347), (2,NULL), (3,NULL), (4,NULL), (5,NULL)}
                     | {(1,NULL), (2,NULL), (3,NULL), (4,NULL), (5,NULL)}
(176015, NULL, NULL) | {(1,176015),(2,NULL), (3,NULL), (4,NULL), (5,NULL)}
                     | {(1,NULL), (2,NULL), (3,NULL), (4,NULL), (5,NULL)}

(10 rows)

Use map_from_entries para atribuir um número de sequência a cada item na lista de produtos e obter o resultado final como um mapa assign-a-sequence-number-return-result-as-map

map_from_entries(array<struct<K, V>>): map<K, V>

Este trecho converte uma matriz de pares de valores-chave em um mapa. É útil ao lidar com dados de par de valor-chave que poderiam se beneficiar de uma estrutura mais organizada e eficiente.

Exemplo

A consulta a seguir cria pares de valores de uma sequência e a matriz productListItems converte esses pares em um mapa usando map_from_entries e seleciona a coluna productListItems original junto com a coluna map_from_entries recém-criada. O resultado é filtrado e limitado com base no intervalo de carimbo de data e hora especificado.

SELECT productListItems,      map_from_entries(zip_with(Sequence(1,Size(productListItems)), productListItems, (x,y) -> struct(x, y))) AS map_from_entries
FROM   geometrixxx_999_xdm_pqs_1batch_10k_rows
WHERE  timestamp > to_timestamp('2017-11-01 00:00:00')
AND    timestamp < to_timestamp('2017-11-02 00:00:00')
LIMIT 10;

Resultado

Os resultados para esse SQL seriam semelhantes aos vistos abaixo.

productListItems     | map_from_entries
---------------------+------------------
(123679, NULL, NULL) | [1 -> "(123679,NULL,NULL)"]
(1346, NULL, NULL)   | [1 -> "(1346, NULL, NULL)"]
(98347, NULL, NULL)  | [1 -> "(98347, NULL, NULL)"]
(176015, NULL, NULL) | [1 -> "(176015, NULL, NULL)"]
(92763, NULL, NULL)  | [1 -> "(92763, NULL, NULL)"]
(48576, NULL, NULL)  | [1 -> "(48576, NULL, NULL)"]
(135778, NULL, NULL) | [1 -> "(135778, NULL, NULL)"]
(123679, NULL, NULL) | [1 -> "(123679, NULL, NULL)"]
(98347, NULL, NULL)  | [1 -> "(98347, NULL, NULL)"]
(167753, NULL, NULL) | [1 -> "(167753, NULL, NULL)"]

(10 rows)

Use map_form_arrays para atribuir números de sequência a itens na lista de produtos e retornar o resultado como um mapa assign-sequence-numbers-to-items-return-the-result-as-a-map

map_form_arrays(array<K>, array<V>): map<K, V>

A função map_form_arrays cria um mapa usando valores emparelhados de duas matrizes.

IMPORTANT
Não deve haver elementos nulos nas chaves.

Exemplo

O SQL abaixo cria um mapa em que as chaves são números sequenciados gerados usando a função Sequence, e os valores são elementos da matriz productListItems. A consulta seleciona a coluna productListItems e usa a função Map_from_arrays para criar o mapa com base na sequência gerada de números e os elementos da matriz. O resultado é limitado a dez linhas e filtrado com base em um intervalo de carimbo de data e hora.

SELECT productListItems,
       Map_from_arrays(Sequence(1, Size(productListItems)), productListItems) AS
       map_from_arrays
FROM   geometrixxx_999_xdm_pqs_1batch_10k_rows
WHERE  Size(productListItems) > 0
       AND timestamp > To_timestamp('2017-11-01 00:00:00')
       AND timestamp < To_timestamp('2017-11-02 00:00:00')
LIMIT  10;

Resultado

Os resultados para esse SQL seriam semelhantes aos vistos abaixo.

productListItems     | map_from_entries
---------------------+------------------
(123679, NULL, NULL) | [1 -> "(123679,NULL,NULL)"]
(1346, NULL, NULL)   | [1 -> "(1346, NULL, NULL)"]
(98347, NULL, NULL)  | [1 -> "(98347, NULL, NULL)"]
(176015, NULL, NULL) | [1 -> "(176015, NULL, NULL)"]
(92763, NULL, NULL)  | [1 -> "(92763, NULL, NULL)"]
(48576, NULL, NULL)  | [1 -> "(48576, NULL, NULL)"]
(135778, NULL, NULL) | [1 -> "(135778, NULL, NULL)"]
(123679, NULL, NULL) | [1 -> "(123679, NULL, NULL)"]
(98347, NULL, NULL)  | [1 -> "(98347, NULL, NULL)"]
(167753, NULL, NULL) | [1 -> "(167753, NULL, NULL)"]

(10 rows)

Use map_concat para concatenar dois mapas em como mapa único concatenate-two-maps-into-as-single-map

map_concat(map<K, V>, ...): map<K, V>

A função map_concat no trecho acima pega vários mapas como argumentos e retorna um novo mapa que combina todos os pares de valores chave dos mapas de entrada. A função concatena vários mapas em um único mapa, e o mapa resultante inclui todos os pares de valores-chave dos mapas de entrada.

Exemplo

O SQL abaixo cria um mapa em que cada item em productListItems é associado a um número de sequência, que é então concatenado com outro mapa em que as chaves são geradas em um intervalo de sequência específico.

SELECT productListItems,
      map_concat(
         map_from_entries(zip_with(Sequence(1,Size(productListItems)), productListItems, (x,y) -> struct(x, y))),
         map_from_arrays(sequence(size(productListItems) + 1, size(productListItems) + size(productListItems)), productListItems) )
FROM geometrixxx_999_xdm_pqs_1batch_10k_rows
WHERE size(productListItems) > 0
AND timestamp > to_timestamp('2017-11-01 00:00:00')
AND timestamp < to_timestamp('2017-11-02 00:00:00')
limit 10;

Resultado

Os resultados para esse SQL seriam semelhantes aos vistos abaixo.

productListItems     | map_from_entries
---------------------+------------------
(123679, NULL, NULL) | [1 -> "(123679,NULL,NULL)",2 -> "(123679, NULL, NULL)"]
(1346, NULL, NULL)   | [1 -> "(1346, NULL, NULL)",2 -> "(1346, NULL, NULL)"]
(98347, NULL, NULL)  | [1 -> "(98347, NULL, NULL)",2 -> "(98347, NULL, NULL)"]
(176015, NULL, NULL) | [1 -> "(176015, NULL, NULL)",2 -> "(176015, NULL, NULL)"]
(92763, NULL, NULL)  | [1 -> "(92763, NULL, NULL)",2 -> "(92763, NULL, NULL)"]
(48576, NULL, NULL)  | [1 -> "(48576, NULL, NULL)",2 -> "(48576, NULL, NULL)"]
(135778, NULL, NULL) | [1 -> "(135778, NULL, NULL)",2 -> "(135778, NULL, NULL)"]
(123679, NULL, NULL) | [1 -> "(123679, NULL, NULL)",2 -> "(123679, NULL, NULL)"]
(98347, NULL, NULL)  | [1 -> "(98347, NULL, NULL)",2 -> "(98347, NULL, NULL)"]
(167753, NULL, NULL) | [1 -> "(167753, NULL, NULL)",2 -> "(167753, NULL, NULL)"]

(10 rows)

Use element_at para recuperar um valor correspondente a 'AAID' no mapa de identidade para cálculo adicional retrieve-a-corresponding-value

element_at(array<T>, Int): T / element_at(map<K, V>, K): V

Para matrizes, o trecho retorna o elemento em um índice especificado (com base em 1) ou o valor associado a uma chave em um mapa. Se o índice for < 0, ele acessará os elementos do último ao primeiro e retornará null se o índice exceder o comprimento da matriz.

Para mapas, ele retorna um valor para a chave fornecida ou nulo se a chave não estiver contida no mapa.

Exemplo

A consulta seleciona a coluna identitymap da tabela geometrixxx_999_xdm_pqs_1batch_10k_rows e extrai o valor associado à chave AAID para cada linha. Os resultados são restritos a linhas que estão dentro do intervalo de carimbo de data e hora especificado, e a consulta limita a saída a dez linhas.

SELECT identitymap,
              Element_at(identitymap, 'AAID')
FROM geometrixxx_999_xdm_pqs_1batch_10k_rows
WHERE timestamp > To_timestamp('2017-11-01 00:00:00')
AND timestamp < To_timestamp('2017-11-02 00:00:00')
LIMIT 10;

Resultado

Os resultados para esse SQL seriam semelhantes aos vistos abaixo.

                                                                  identitymap                                            |  element_at(identitymap, AAID)
-------------------------------------------------------------------------------------------------------------------------+-------------------------------------
[AAID -> "(3617FBB942466D79-5433F727AD6A0AD, false)",ECID -> "(67383754798169392543508586197135045866,true)"]            | (3617FBB942466D79-5433F727AD6A0AD, false)
[AAID -> "[AAID -> "(533F56A682C059B1-396437F68879F61D, false)",ECID -> "(91989370462250197735311833131353001213,true)"] | (533F56A682C059B1-396437F68879F61D, false)
[AAID -> "(22E195F8A8ECCC6A-A39615C93B72A9F, false)",ECID -> "(57699241367342030964647681192998909474,true)"]            | (22E195F8A8ECCC6A-A39615C93B72A9F, false)
[AAID -> "(6A60527B9D66CCB9-29638A632B45E9, false)",ECID -> "(50117234882064422833184021414056250576,true)"]             | (6A60527B9D66CCB9-29638A632B45E9, false)
[AAID -> "(64FB4DC317E21B59-2A23602D234647E7, false)",ECID -> "(79785479785408621882908938960039330887,true)"]           | (64FB4DC317E21B59-2A23602D234647E7, false)
[AAID -> "(2E70E8CF6DB1DE86-270E55BBBA58B9C1, false)",ECID -> "(80073674009951685326146914344189474476,true)"]           | (2E70E8CF6DB1DE86-270E55BBBA58B9C1, false)
[AAID -> "(22E195F8A8ECCC6A-A39615C93B72A9F, false)",ECID -> "(57699241367342030964647681192998909474,true)"]            | (22E195F8A8ECCC6A-A39615C93B72A9F, false)
[AAID -> "(1CFB3297C3146F2F-28D6902A610BA3B1, false)",ECID -> "(88251082790399360979074868101758236669,true)"]           | (1CFB3297C3146F2F-28D6902A610BA3B1, false)
[AAID -> "(533F56A682C059B1-396437F68879F61D, false)",ECID -> "(91989370462250197735311833131353001213,true)"]           | (533F56A682C059B1-396437F68879F61D, false)
(10 rows)

Usar cardinalidade para localizar o número de identidades no mapa de identidades find-the-number-of-identities-in-the-identity-map

cardinality(array<T>): Int / cardinality(map<K, V>): Int

Este trecho retorna o tamanho de uma determinada matriz ou mapa e fornece um alias. Ele retorna -1 se o valor for nulo.

Exemplo

A consulta abaixo recupera a coluna identitymap, e a função Cardinality calcula o número de elementos em cada mapa dentro de identitymap. Os resultados são limitados a dez linhas e filtrados com base em um intervalo de carimbo de data e hora especificado.

SELECT identitymap,
       Cardinality(identitymap)
FROM   geometrixxx_999_xdm_pqs_1batch_10k_rows
WHERE timestamp > To_timestamp('2017-11-01 00:00:00')
AND timestamp < To_timestamp('2017-11-02 00:00:00')
LIMIT  10;

Resultado

Os resultados para esse SQL seriam semelhantes aos vistos abaixo.

                                                                  identitymap                                            |  size(identitymap)
-------------------------------------------------------------------------------------------------------------------------+-------------------------------------
[AAID -> "(3617FBB942466D79-5433F727AD6A0AD, false)",ECID -> "(67383754798169392543508586197135045866,true)"]            |      2
[AAID -> "[AAID -> "(533F56A682C059B1-396437F68879F61D, false)",ECID -> "(91989370462250197735311833131353001213,true)"] |      2
[AAID -> "(22E195F8A8ECCC6A-A39615C93B72A9F, false)",ECID -> "(57699241367342030964647681192998909474,true)"]            |      2
[AAID -> "(6A60527B9D66CCB9-29638A632B45E9, false)",ECID -> "(50117234882064422833184021414056250576,true)"]             |      2
[AAID -> "(64FB4DC317E21B59-2A23602D234647E7, false)",ECID -> "(79785479785408621882908938960039330887,true)"]           |      2
[AAID -> "(2E70E8CF6DB1DE86-270E55BBBA58B9C1, false)",ECID -> "(80073674009951685326146914344189474476,true)"]           |      2
[AAID -> "(22E195F8A8ECCC6A-A39615C93B72A9F, false)",ECID -> "(57699241367342030964647681192998909474,true)"]            |      2
[AAID -> "(1CFB3297C3146F2F-28D6902A610BA3B1, false)",ECID -> "(88251082790399360979074868101758236669,true)"]           |      2
[AAID -> "(533F56A682C059B1-396437F68879F61D, false)",ECID -> "(91989370462250197735311833131353001213,true)"]           |      2
(10 rows)

Use array_distinct para localizar os elementos distintos em productListItems find-distinct-elements

array_distinct(array<T>): array<T>

O trecho acima remove valores duplicados da matriz especificada.

Exemplo

A consulta abaixo seleciona a coluna productListItems, remove os itens duplicados das matrizes e limita a saída a dez linhas com base em um intervalo de carimbo de data/hora especificado.

SELECT productListItems,
              Array_distinct(productListItems)
FROM geometrixxx_999_xdm_pqs_1batch_10k_rows
WHERE timestamp > To_timestamp('2017-11-01 00:00:00')
AND timestamp < To_timestamp('2017-11-02 00:00:00')
LIMIT 10;

Resultado

Os resultados para esse SQL seriam semelhantes aos vistos abaixo.

productListItems     | array_distinct(productListItems)
---------------------+---------------------------------
                     |
(123679, NULL, NULL) | (123679, NULL, NULL)
                     |
                     |
(1346,NULL, NULL)    | (1346,NULL, NULL)
                     |
(98347, NULL, NULL)  | (98347, NULL, NULL)
                     |
(176015, NULL, NULL) | (176015, NULL, NULL)
                     |

(10 rows)

Funções adicionais de ordem superior additional-higher-order-functions

Os seguintes exemplos de funções de ordem superior são explicados como parte do caso de uso recuperar registros semelhantes. Um exemplo e uma explicação do uso de cada função são fornecidos na respectiva seção desse documento.

O exemplo de função transformabrange a geração de tokens de uma lista de produtos.

O exemplo de função filterdemonstra uma extração mais refinada e precisa de informações relevantes de dados de texto.

A função reducefornece uma maneira de derivar valores cumulativos ou agregações, que podem ser fundamentais em vários processos analíticos e de planejamento.

recommendation-more-help
ccf2b369-4031-483f-af63-a93b5ae5e3fb