Funções do Hive: Exemplos de funções integradas e UDF (definidas pelo usuário)

⚡ Resumo Inteligente

As funções do Hive se dividem em dois grupos: funções integradas que acompanham o mecanismo e abrangem coleções, datas, operações matemáticas, condicionais, strings e outras tarefas diversas, e funções definidas pelo usuário, escritas em linguagem natural. Java A lógica que o Hive não fornece.

  • 📚 Seis famílias integradas: Funções de coleção, data, matemáticas, condicionais, de string e diversas podem ser chamadas diretamente dentro do HiveQL.
  • 🧾 As assinaturas importam: Cada função possui uma lista fixa de argumentos e um tipo de retorno documentado, portanto, o tipo de retorno determina onde ela pode ser usada.
  • 🧩 A UDF preenche as lacunas: Quando não existe uma função integrada, um Java A classe que estende org.apache.hadoop.hive.ql.exec.UDF fornece a operação que faltava.
  • 🔢 Três formatos de função personalizada: UDF retorna uma linha por vez, UDAF consolida várias linhas em uma só, e UDTF expande uma linha em várias.
  • 🛠️ Inscrição em duas etapas: ADD JAR adiciona o código ao classpath e CREATE TEMPORARY FUNCTION associa um nome à classe.
  • ♻️ A reutilização é o objetivo: Uma UDF testada, como um stemmer, pode ser chamada em todas as consultas em vez de ser reescrita a cada vez.

Funções do Hive: Funções integradas e definidas pelo usuário

As funções são criadas com um propósito específico: executar operações como operações matemáticas, aritméticas, lógicas e relacionais nos operandos dos nomes das colunas da tabela.

Funções incorporadas

Estas são funções que já estão disponíveis no Hive. Primeiro, temos que verificar os requisitos do aplicativo e, então, podemos usar essas funções integradas em nossos aplicativos. Podemos chamar essas funções diretamente em nossa aplicação.

A sintaxe e os tipos são mencionados na seção a seguir.

Tipos de funções integradas no Hive:

  • Funções de coleção
  • Funções de Data
  • Funções Matemáticas
  • Funções Condicionais
  • Funções de String
  • Diversos. Funções

Cada uma das seis famílias é abordada abaixo com suas respectivas assinaturas de função e tipos de retorno.

Funções de coleção

Essas funções são usadas para coleções. Coleções significam o grupo de elementos.ping de elementos, e retornam um único elemento ou uma matriz de elementos, dependendo do tipo de retorno mencionado no nome da função.

Tipo de Devolução Nome da Função Descrição
INT tamanho(Mapa ) Ele buscará e fornecerá o número de componentes no tipo de mapa.
INT tamanho (matriz ) Ele buscará e retornará o número de elementos no tipo de array.
Variedade map_keys(Map ) A função buscará e retornará um array contendo as chaves do mapa de entrada. O array não está ordenado.
Variedade map_values(Map ) A função buscará e retornará um array contendo os valores do mapa de entrada. O array não está ordenado.
Variedade ordenar_array(Array ) Ordena o array de entrada em ordem crescente de seus elementos e o retorna.
Booleano array_contém(Array , valor) Retorna VERDADEIRO se o array contiver o valor passado como segundo argumento.

Funções de Data

Essas funções são usadas para realizar manipulações de datas e conversões de tipos de data de um tipo para outro:

Nome da Função Tipo de Devolução Descrição
carimbo_de_tempo_unix() BigInt Vamos obter a atual Unix Carimbo de data/hora em segundos. O valor não é fixo para toda a consulta.
to_date(string timestamp) dados A função irá buscar e fornecer a parte da data de uma string de registro de data e hora.
ano (string data) INT Ele irá buscar e fornecer ao ano parte de uma data ou uma string de carimbo de data/hora
trimestre(data/timestamp/string) INT Ele irá buscar e fornecer o trimestre do ano para uma data, carimbo de data/hora ou string no intervalo de 1 a 4
mês(string data) INT Ele fornecerá ao mês parte de uma data ou uma string de carimbo de data/hora
hora(string data) INT Ele irá buscar e fornecer a hora do registro de data e hora.
minuto(string data) INT Ele buscará e fornecerá o minuto do registro de data e hora.
date_sub(string data inicial, int dias) dados Ele buscará e fornecerá o resultado da sub-rotina.tracting um número de dias a partir da data de início
data_atual dados A consulta irá buscar e fornecer a data atual no início da avaliação.
último_dia(string data) corda A função buscará e exibirá o último dia do mês a que a data pertence.
trunc(string data, formato string) corda A função buscará e fornecerá a data truncada na unidade especificada pelo formato. Os formatos suportados: MÊS/SEG/MM, ANO/AAAA/AA.

Funções Matemáticas

Essas funções são usadas para operações matemáticas. Em vez de criar UDFs (Funções Definidas pelo Usuário), temos algumas funções matemáticas integradas no Hive.

Nome da Função Tipo de Devolução Descrição
rodada (DUPLO X) DUPLO A função irá buscar e retornar o valor BIGINT arredondado de X.
rodada (DUPLO X, INT d) DUPLO A função buscará e retornará X arredondado para d casas decimais.
redondo (DUPLO X) DUPLO A função buscará e retornará o valor BIGINT arredondado de X usando o modo de arredondamento HALF_EVEN, também conhecido como arredondamento bancário.
piso (DUPLO X) GRANDE A função buscará e retornará o maior valor BIGINT que seja igual ou menor que o valor X.
teto (DUPLO a), teto (DUPLO a) GRANDE A função buscará e retornará o menor valor BIGINT que seja igual ou maior que o valor `a`.
rand(), rand(semente INT) DUPLO A função irá buscar e retornar um número aleatório distribuído uniformemente entre 0 e 1. Fornecer uma semente torna a sequência repetível.

Funções Condicionais

Essas funções são usadas para verificações de valores condicionais.

Nome da Função Tipo de Devolução Descrição
if(Boolean testCondition, T valorTrue, T valorFalseOrNull) T O resultado será `valueTrue` quando `testCondition` for verdadeira e `valueFalseOrNull` caso contrário.
é nulo(X) Booleano A função buscará e retornará verdadeiro se X for NULL e falso caso contrário.
não é nulo(X) Booleano A função buscará e retornará verdadeiro se X não for NULL e falso caso contrário.
nvl(T valor, T valor_padrão) T Será retornado o valor padrão quando o valor for NULL, e o valor padrão caso contrário.

Funções de String

As seguintes funções realizam manipulações e operações com strings.

Nome da Função Tipo de Devolução Descrição
inverter(string X) corda Isso fornecerá a string invertida de X
rpad(string str, comprimento interno, string pad) corda Ele buscará e fornecerá uma string preenchida à direita com um pad até um comprimento total de comprimento.
rtrim(string X) corda A função irá buscar e retornar a string resultante da remoção dos espaços do final (lado direito) de X.
Por exemplo, rtrim('resultados') resulta em 'resultados'
espaço (INTn) corda A função irá buscar e retornar uma sequência de n espaços.
dividir(STRING str, STRING pat) ordem Divide str em torno de pat (pat é uma expressão regular).
str_to_map(texto[, delimitador1, delimitador2]) mapa O comando irá dividir o texto em pares chave-valor usando dois delimitadores. O delimitador1 separa os pares e o delimitador2 divide cada par.

Diversos. Funções

Diversas funções integradas não pertencem a nenhuma das famílias acima. Elas abrangem funções de hash, informações de sessão e chamadas arbitrárias. Java métodos.

Nome da Função Tipo de Devolução Descrição
hash(a1[, a2…]) INT Retorna um valor hash dos argumentos.
usuário_atual() corda Retorna o nome de usuário atual do gerenciador de autenticação configurado.
banco_de_dados_atual() corda Retorna o nome do banco de dados atual.
md5 (string/binário) corda Retorna o checksum MD5 de 128 bits como uma string de 32 dígitos hexadecimais, ou NULL para um argumento NULL.
sha1 (string/binário) corda Retorna o resumo SHA-1 do argumento como uma string hexadecimal.
crc32 (string/binário) BigInt Retorna o valor de verificação de redundância cíclica de um argumento de string ou binário.
versão() corda Retorna a versão do Hive como um número de compilação seguido por um hash de compilação.
refletir(classe, método[, arg1…]) varia Chama um Java método por correspondência da assinatura do argumento, usando reflexão. java_method() é um sinônimo

UDFs (funções definidas pelo usuário)

No Hive, os usuários podem definir suas próprias funções para atender a determinados requisitos do cliente. Essas funções são conhecidas como UDFs (Funções Definidas pelo Usuário) no Hive. As funções definidas pelo usuário são escritas em Java para módulos específicos.

Algumas UDFs são projetadas especificamente para a reutilização de código em frameworks de aplicativos. O desenvolvedor escreve essas funções em Java e integra essas UDFs com o Hive.

Durante a execução da consulta, o desenvolvedor pode usar o código diretamente, e as UDFs (Funções Definidas pelo Usuário) retornarão os resultados de acordo com as tarefas definidas pelo usuário. Isso proporciona alto desempenho em termos de codificação e execução.

Por exemplo, para stemming de strings, não temos nenhuma função predefinida no Hive. Para isso, podemos escrever uma UDF de stemming em JavaSempre que precisarmos da funcionalidade de stem, podemos chamar diretamente essa UDF de stem no Hive.

Aqui, a funcionalidade de stemming significa derivar palavras de suas palavras-raiz. Um algoritmo de stemming reduz as palavras “wishing”, “wished” e “wishes” à palavra-raiz “wish”. Para realizar esse tipo de funcionalidade, podemos escrever uma UDF em Java e integrá-lo com Colméia.

Dependendo do caso de uso, a UDF pode ser escrita para aceitar e produzir diferentes quantidades de valores de entrada e saída.

O tipo geral de UDF aceita um único valor de entrada e produz um único valor de saída. Se a UDF for usada em uma consulta, ela será chamada uma vez para cada linha no conjunto de dados resultante.

Por outro lado, uma função pode aceitar um grupo de valores como entrada e retornar um único valor de saída. Essa diferença é o que distingue os três tipos de funções personalizadas descritos a seguir.

UDF vs UDAF vs UDTF no Hive

As funções personalizadas no Hive são agrupadas de acordo com a quantidade de linhas que recebem e a quantidade que retornam. Escolher o tipo errado é o motivo mais comum para uma função personalizada se recusar a compilar ou retornar uma única linha quando se esperava uma tabela.

Formato Linhas de entrada → linhas de saída Classe para estender Exemplos integrados
UDF Uma linha → uma linha org.apache.hadoop.hive.ql.exec.UDF comprimento(), arredondar(), inverter()
UDAF Muitas linhas → uma linha org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolver contar(), min(), max()
UDTF Uma linha → várias linhas org.apache.hadoop.hive.ql.udf.generic.GenericUDTF explode(), json_tuple(), parse_url_tuple()

Da tabela decorrem duas regras práticas:

  • Uma UDAF (Função de Atribuição Única) é quase sempre usada em conjunto com uma cláusula GROUP BY, porque ela reduz cada grupo a uma única linha.
  • Uma UDTF não pode ser selecionada juntamente com outras colunas na mesma lista SELECT, portanto, normalmente é usada com uma LATERAL VIEW.

Existe também uma segunda classe base, mais capaz, para trabalho em nível de linha, a GenericUDF, que aceita tipos complexos como arrays, mapas e structs, além de um número variável de argumentos.

Como escrever e registrar uma UDF no Hive

O exemplo de caule descrito acima pode ser construído como uma função real em quatro etapas. Nada além de um Java É necessário um compilador e uma sessão Hive em execução.

Passo 1) Escreva para Java Classe que estende UDF e implementa um método público evaluate(). O Hive chama evaluate() uma vez por linha, portanto o método deve lidar com uma entrada NULL.

package com.guru99.hive.udf;

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

public final class Stem extends UDF {

    public Text evaluate(final Text input) {
        if (input == null) {
            return null;
        }
        String word = input.toString().toLowerCase();
        if (word.endsWith("ing")) {
            word = word.substring(0, word.length() - 3);
        } else if (word.endsWith("ed") || word.endsWith("es")) {
            word = word.substring(0, word.length() - 2);
        }
        return new Text(word);
    }
}

Passo 2) Compile a classe e empacote-a em um arquivo JAR, por exemplo, hive-udf-1.0.jar, juntamente com quaisquer classes das quais ela dependa.

Passo 3) Coloque o arquivo JAR no classpath do Hive e associe um nome de função à classe. Uma função temporária existe apenas durante a sessão atual.

ADD JAR /home/hduser/hive-udf-1.0.jar;

CREATE TEMPORARY FUNCTION stem AS 'com.guru99.hive.udf.Stem';

Passo 4) Chame a nova função exatamente como uma função integrada. Aplicada às palavras "wishing", "wished" e "wishes", esta classe retorna "wish" para todas as três.

SELECT word, stem(word) FROM words;

Para manter a função disponível para todas as sessões e todos os usuários, registre-a permanentemente em um banco de dados. O arquivo JAR deve estar em um caminho que todo o cluster possa ler, o que normalmente significa HDFS.

CREATE FUNCTION default.stem AS 'com.guru99.hive.udf.Stem'
USING JAR '/user/hive/udfs/hive-udf-1.0.jar';

Uma única classe pode declarar mais de um método `evaluate()`. O Hive compara a chamada com as assinaturas dos argumentos, e é assim que uma função pode aceitar tanto uma string quanto um número inteiro.

Perguntas Frequentes

SHOW FUNCTIONS lista todos os nomes registrados, incluindo os personalizados. DESCRIBE FUNCTION nome imprime uma assinatura de uma linha e DESCRIBE FUNCTION EXTENDED nome adiciona exemplos de uso quando a classe de implementação os fornece.

Quase sempre é um problema de nome ou escopo: a string após AS deve ser o nome completo da classe, e ADD JAR só se aplica à sessão que o executou. Reconectar remove tanto o arquivo JAR quanto qualquer função temporária.

Use `GenericUDF` quando a função receber tipos complexos como arrays, mapas ou structs, um número variável de argumentos ou precisar validar os tipos dos argumentos. A classe `UDF` simples resolve os tipos por reflexão e lida apenas com tipos primitivos `Writable`.

Uma UDF verdadeira deve ser executada na JVM. Para outras linguagens, Colméia oferece a cláusula TRANSFORM, que transmite cada linha por meio de um script externo, como por exemplo: Python sobre entrada e saída padrão. É mais lento, mas evita Java inteiramente.

Sim, podem. A função `evaluate()` é executada uma vez por linha, portanto, a lógica custosa é multiplicada pela contagem de linhas, e a alocação de objetos dentro do método aumenta a pressão sobre o coletor de lixo. Prefira uma função integrada quando houver uma disponível e mantenha a função `evaluate()` livre de operações de E/S.

Não. Os nomes das funções não diferenciam maiúsculas de minúsculas, portanto ROUND(), Round() e round() são a mesma função. Java O nome da classe na cláusula AS é uma questão diferente e deve corresponder exatamente à classe compilada, incluindo seu pacote.

Os assistentes de aprendizado de máquina mapeiam uma descrição em linguagem natural para as assinaturas candidatas e avisam quando um tipo de retorno não corresponde à coluna de destino. Verifique a sugestão em relação à assinatura documentada, pois os nomes gerados às vezes pertencem a outro dialeto SQL.

A função gera um esqueleto utilizável — a declaração da classe, as importações e um método `evaluate()` — a partir de um comentário que descreve a operação. O tratamento de valores nulos, os tipos graváveis ​​e a etapa de empacotamento ainda precisam ser revisados, e a função deve ser testada em linhas reais.

Resuma esta postagem com: