Funkce Hive: Příklad vestavěných a UDF (uživatelsky definovaných) funkcí

⚡ Chytré shrnutí

Funkce Hive se dělí do dvou skupin: vestavěné funkce, které jsou součástí enginu a pokrývají kolekce, data, matematické, podmíněné, řetězcové a různé operace, a uživatelem definované funkce napsané v Java pro logiku Hive neposkytuje.

  • ???? Šest vestavěných rodin: Kolekční, datové, matematické, podmíněné, řetězcové a různé funkce lze volat přímo v HiveQL.
  • 🧾 Podpisy jsou důležité: Každá funkce má pevný seznam argumentů a zdokumentovaný návratový typ, takže návratový typ určuje, kde ji lze použít.
  • 🧩 UDF vyplňuje mezery: Pokud neexistuje žádná vestavěná funkce, a Java Třída rozšiřující org.apache.hadoop.hive.ql.exec.UDF dodává chybějící operaci.
  • 🔢 Tři tvary vlastní funkce: UDF vrací jeden řádek na řádek, UDAF sbalí více řádků do jednoho a UDTF rozbalí jeden řádek do mnoha.
  • 🛠️ Registrace ve dvou krocích: ADD JAR vloží kód do cesty ke třídě a CREATE TEMPORARY FUNCTION naváže název na třídu.
  • ♻️ Jde o opětovné použití: Z každého dotazu lze volat jednu testovanou UDF, například stemmer, místo aby byla pokaždé přepisována.

Funkce Hive: Vestavěné a uživatelem definované funkce

Funkce jsou vytvořeny pro specifický účel k provádění operací, jako jsou matematické, aritmetické, logické a relační operace s operandy názvů sloupců tabulky.

Vestavěné funkce

Toto jsou funkce, které jsou již v Hive k dispozici. Nejprve musíme zkontrolovat požadavek aplikace a poté můžeme tyto vestavěné funkce použít v našich aplikacích. Tyto funkce můžeme volat přímo v naší aplikaci.

Syntaxe a typy jsou uvedeny v následující části.

Typy vestavěných funkcí v Hive:

  • Sběrné funkce
  • Funkce data
  • Matematické funkce
  • Podmíněné funkce
  • Řetězcové funkce
  • Různé Funkce

Každá ze šesti rodin je níže popsána spolu s jejími funkčními signaturami a návratovými typy.

Sběrné funkce

Tyto funkce se používají pro kolekce. Kolekce znamenají skupinuping prvků a vracejí jeden prvek nebo pole prvků v závislosti na návratovém typu uvedeném v názvu funkce.

Typ vrácení Název funkce Description
INT velikost (mapa ) Načte a vrátí počet komponent v typu mapy.
INT velikost (pole ) Načte a vrátí počet prvků v typu pole
Pole map_keys(Mapa ) Načte a vrátí pole obsahující klíče vstupní mapy. Pole je neuspořádané.
Pole map_values(Mapa ) Načte a vrátí pole obsahující hodnoty vstupní mapy. Pole je neuspořádané.
Pole sort_array(Pole ) Seřadí vstupní pole vzestupně podle jeho prvků a vrátí je.
Boolean pole_obsahuje(Pole , hodnota) Vrátí hodnotu TRUE, pokud pole obsahuje hodnotu předanou jako druhý argument.

Funkce data

Tyto se používají k provádění manipulací s daty a převodu typů dat z jednoho typu na jiný typ:

Název funkce Typ vrácení Description
unix_timestamp() BigInt Dostaneme aktuální Unix časové razítko v sekundách. Hodnota není pevně stanovena pro celý dotaz.
to_date(řetězec časové razítko) datum Načte a vrátí datumovou část řetězce časového razítka.
rok (řetězcové datum) INT Načte a poskytne rok část data nebo řetězec časového razítka
čtvrtletí (datum/časové razítko/řetězec) INT Načte a uvede čtvrtletí roku pro datum, časové razítko nebo řetězec v rozsahu 1 až 4
měsíc (řetězcové datum) INT Měsíc poskytne část data nebo řetězec časového razítka
hodina (řetězcové datum) INT Načte a poskytne hodinu časového razítka.
minuta (datum řetězce) INT Načte a uvede minutu časového razítka.
date_sub(řetězec počáteční datum, int dny) datum Načte a vrátí výsledek subtracněkolik dní od data zahájení
aktuální_datum datum Načte a zobrazí aktuální datum na začátku vyhodnocení dotazu.
last_day(řetězec data) šňůra Načte a vrátí poslední den měsíce, do kterého datum patří.
trunc(datum řetězce, formát řetězce) šňůra Načte a vrátí datum zkrácené na jednotky určené formátem. Podporované formáty: MĚSÍC/PO/MM, ROK/RRRR/RR.

Matematické funkce

Tyto funkce se používají pro matematické operace. Místo vytváření UDF máme v Hive některé vestavěné matematické funkce.

Název funkce Typ vrácení Description
kulaté (DVOJKRÁT X) DVOJNÁSOBEK Načte a vrátí zaokrouhlenou hodnotu BIGINT pro X.
kulaté (DVOJNÁSOBNÉ X, INT d) DVOJNÁSOBEK Načte a vrátí X zaokrouhlené na d desetinných míst
broušené (DVOJKRÁT X) DVOJNÁSOBEK Načte a vrátí zaokrouhlenou hodnotu BIGINT pro X pomocí zaokrouhlovacího režimu HALF_EVEN, známého také jako bankéřské zaokrouhlování.
patro (DVOJITÉ X) VELKÝ Načte a vrátí maximální hodnotu BIGINT, která je rovna nebo menší než hodnota X.
strop (DOUBLE a), strop (DOUBLE a) VELKÝ Načte a vrátí minimální hodnotu BIGINT, která je rovna nebo větší než hodnota a.
rand(), rand(semeno INT) DVOJNÁSOBEK Načte a vrátí náhodné číslo, které je rovnoměrně rozloženo od 0 do 1. Zadáním semene se sekvence stane opakovatelnou.

Podmíněné funkce

Tyto funkce se používají pro podmíněné kontroly hodnot.

Název funkce Typ vrácení Description
if(Booleovská testová podmínka, T hodnotaTrue, T hodnotaFalseOrNull) T Pokud je testCondition pravdivý, vrátí hodnotu valueTrue, v opačném případě hodnotu valueFalseOrNull.
je null(X) Boolean Pokud je X NULL, načte hodnotu true, jinak vrátí hodnotu false.
není null(X) Boolean Pokud X není NULL, načte hodnotu true, jinak vrátí hodnotu false.
nvl(hodnota T, výchozí_hodnota T) T Pokud je hodnota NULL, vrátí hodnotu default_value, jinak vrátí hodnotu value.

Řetězcové funkce

Manipulace s řetězci a operace s nimi jsou zpracovávány následujícími funkcemi.

Název funkce Typ vrácení Description
reverzní(řetězec X) šňůra Poskytne obrácený řetězec X
rpad(string string, int length, string pad) šňůra Načte a vrátí str doplněný vpravo pomocí padu na celkovou délku length
rtrim(řetězec X) šňůra Načte a vrátí řetězec, který vznikne oříznutím mezer z konce (pravé strany) X.
Například, rtrim(' results ') výsledky v ' results'
mezera (INT n) šňůra Načte a vrátí řetězec n mezer.
split(STRING str, STRING pat) řada Rozdělí str kolem pat (pat je regulární výraz).
str_to_map(text[, oddělovač1, oddělovač2]) mapa Rozdělí text na páry klíč-hodnota pomocí dvou oddělovačů. Oddělovač1 odděluje páry a oddělovač2 rozděluje každý pár.

Různé Funkce

Několik vestavěných funkcí nepatří do žádné z výše uvedených rodin. Patří sem hašování, informace o relaci a volání libovolných funkcí. Java metody.

Název funkce Typ vrácení Description
hash(a1[, a2…]) INT Vrátí hašovací hodnotu argumentů
aktuální_uživatel() šňůra Vrátí aktuální uživatelské jméno z nakonfigurovaného správce ověřovacích údajů.
aktuální_databáze() šňůra Vrátí název aktuální databáze
md5(řetězec/binární) šňůra Vrací 128bitový kontrolní součet MD5 jako řetězec 32 hexadecimálních číslic nebo NULL pro argument NULL.
sha1(řetězec/binární) šňůra Vrátí SHA-1 digest argumentu jako hexadecimální řetězec.
crc32(řetězec/binární) BigInt Vrátí hodnotu cyklické redundantní kontroly řetězce nebo binárního argumentu
verze() šňůra Vrátí verzi Hive jako číslo sestavení následované hašem sestavení.
reflektovat(třída, metoda[, arg1…]) se liší Volá Java metodu porovnáním signatury argumentu pomocí reflexe. java_method() je synonymum

UDF (uživatelem definované funkce)

V Hive si uživatelé mohou definovat vlastní funkce, které splňují určité požadavky klienta. Tyto funkce se v Hive nazývají UDF. Uživatelsky definované funkce jsou psány v Java pro konkrétní moduly.

Některé UDF jsou speciálně navrženy pro opětovné použití kódu v aplikačních frameworkech. Vývojář píše tyto funkce v Java a integruje tyto UDF s Hive.

Během provádění dotazů může vývojář přímo použít kód a UDF vrátí výstupy podle uživatelem definovaných úloh. To poskytuje vysoký výkon z hlediska kódování i provádění.

Například pro stemming řetězců nemáme v Hive žádnou předdefinovanou funkci. Pro to můžeme napsat stem UDF v JavaKdekoli potřebujeme funkcionalitu stemu, můžeme tuto UDF stemu v Hive přímo zavolat.

Zde se pod pojmem stem funkcionalita rozumí odvozování slov z jejich kořenů. Stemming algoritmus redukuje slova „wishing“, „wished“ a „wishes“ na kořen slova „wish“. Pro provádění tohoto typu funkcionality můžeme napsat UDF v Java a integrovat jej s Úl.

V závislosti na případu použití lze UDF napsat tak, aby přijímala a produkovala různý počet vstupních a výstupních hodnot.

Obecný typ UDF přijme jednu vstupní hodnotu a vygeneruje jednu výstupní hodnotu. Pokud je UDF použita v dotazu, bude UDF volána jednou pro každý řádek ve výsledné datové sadě.

V opačném směru může funkce přijímat skupinu hodnot jako vstup a zároveň vracet jednu výstupní hodnotu. Tento rozdíl odděluje tři typy vlastních funkcí popsaných dále.

UDF vs. UDAF vs. UDTF v Hive

Vlastní funkce v Hive jsou seskupeny podle počtu vstupních a výstupních řádků. Výběr nesprávného typu je nejčastějším důvodem, proč se vlastní funkce odmítá kompilovat nebo vrací pouze jeden řádek tam, kde se očekávala tabulka.

Typ Řádky dovnitř → řádky ven Třída k rozšíření Vestavěné příklady
UDF Jeden řádek → jeden řádek org.apache.hadoop.hive.ql.exec.UDF délka(), zaokrouhlení(), obrácené()
UDAF Mnoho řádků → jeden řádek org.apache.hadoop.hive.ql.udf.generic.AbstracGenerický UDAFResolver počet(), min(), max()
UDTF Jeden řádek → mnoho řádků org.apache.hadoop.hive.ql.udf.generic.GenericUDTF explodovat(), json_tuple(), parse_url_tuple()

Z tabulky vyplývají dvě praktická pravidla:

  • UDAF je téměř vždy spárován s klauzulí GROUP BY, protože ta sbalí každou skupinu na jeden řádek.
  • UDTF nelze vybrat vedle jiných sloupců ve stejném seznamu SELECT, proto se obvykle používá s LATERAL VIEW.

Existuje také druhá, výkonnější základní třída pro práci na úrovni řádků, GenericUDF, která akceptuje komplexní typy, jako jsou pole, mapy a struktury, a variabilní počet argumentů.

Jak napsat a zaregistrovat UDF v Hive

Výše popsaný příklad stemu lze sestavit jako reálnou funkci ve čtyřech krocích. Nic jiného než Java Je vyžadován kompilátor a spuštěná relace Hive.

Krok 1) Napsat Java třída, která rozšiřuje UDF a implementuje veřejnou metodu evaluate(). Hive volá evaluate() jednou na řádek, takže metoda musí zpracovávat vstup 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);
    }
}

Krok 2) Zkompilujte třídu a zabalte ji do souboru JAR, například hive-udf-1.0.jar, spolu se všemi třídami, na kterých závisí.

Krok 3) Vložte JAR do třídní cesty Hive a navažte název funkce na třídu. Dočasná funkce je platná pouze pro aktuální relaci.

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

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

Krok 4) Novou funkci zavolejte přesně jako vestavěnou. V případě slov „wishing“, „wished“ a „wishes“ tato třída vrátí „wish“ pro všechna tři.

SELECT word, stem(word) FROM words;

Aby byla funkce dostupná pro každou relaci a každého uživatele, zaregistrujte ji trvale v databázi. Soubor JAR musí být umístěn na cestě, kterou může číst celý cluster, což obvykle znamená HDFS.

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

Jedna třída může deklarovat více metod evaluate(). Hive porovnává volání s signaturami argumentů, což znamená, že jedna funkce může přijímat jak řetězec, tak celé číslo.

Nejčastější dotazy

SHOW FUNCTIONS vypíše všechny registrované názvy, včetně vlastních. DESCRIBE FUNCTION název vypíše jednořádkový podpis a DESCRIBE FUNCTION EXTENDED název přidá příklady použití tam, kde je implementující třída poskytuje.

Téměř vždy se jedná o problém s názvem nebo rozsahem: řetězec za AS musí být plně kvalifikovaný název třídy a příkaz ADD JAR se vztahuje pouze na relaci, která jej spustila. Opětovné připojení zruší jak soubor JAR, tak i všechny dočasné funkce.

Použijte GenericUDF, když funkce přijímá složité typy, jako jsou pole, mapy nebo struktury, proměnný počet argumentů nebo potřebuje sama ověřit typy argumentů. Jednoduchá třída UDF řeší typy reflexí a zpracovává pouze primitivní zapisovatelné objekty.

Skutečná UDF musí běžet na JVM. Pro ostatní jazyky, Úl nabízí klauzuli TRANSFORM, která streamuje každý řádek pomocí externího skriptu, například Python oproti standardnímu vstupu a výstupu. Je to pomalejší, ale vyhýbá se Java zcela.

Mohou. evaluate() se spouští jednou za řádek, takže nákladná logika se vynásobí počtem řádků a alokace objektů uvnitř metody zvyšuje tlak na garbage collection. Upřednostňujte vestavěnou funkci, pokud nějaká existuje, a udržujte evaluate() bez I/O operací.

Ne. Názvy funkcí se rozlišují bez rozlišování velkých a malých písmen, takže ROUND(), Round() a round() jsou stejné funkce. Java Název třídy v klauzuli AS je jiná věc a musí přesně odpovídat kompilované třídě, včetně jejího balíčku.

Asistenti strojového učení mapují popis v prostém jazyce na kandidátské signatury a varují, když návratový typ neodpovídá cílovému sloupci. Ověřte návrh oproti zdokumentované signatuře, protože vygenerované názvy někdy patří do jiného dialektu SQL.

Vytváří použitelnou kostru – deklaraci třídy, importy a metodu evaluate() – z komentáře popisujícího operaci. Zpracování hodnot Null, zapisovatelné typy a krok balení je stále třeba zkontrolovat a funkci je nutné otestovat na reálných řádcích.

Shrňte tento příspěvek takto: