Hive Fonksiyonları: Yerleşik ve Kullanıcı Tanımlı (UDF) Örnekler

⚡ Akıllı Özet

Hive fonksiyonları iki gruba ayrılır: motorla birlikte gelen ve koleksiyon, tarih, matematiksel, koşullu, dize ve çeşitli işlemleri kapsayan yerleşik fonksiyonlar ve kullanıcı tanımlı, C++ dilinde yazılmış fonksiyonlar. Java Hive'ın sağlamadığı mantık için.

  • 📚 Altı adet dahili aile: Koleksiyon, tarih, matematiksel, koşullu, dize ve çeşitli diğer fonksiyonlar doğrudan HiveQL içinden çağrılabilir.
  • 🧾 İmzalar önemlidir: Her fonksiyonun sabit bir argüman listesi ve belgelenmiş bir dönüş türü vardır, dolayısıyla dönüş türü fonksiyonun nerede kullanılabileceğini belirler.
  • 🧩 UDF boşlukları dolduruyor: Yerleşik bir işlev bulunmadığında, Java org.apache.hadoop.hive.ql.exec.UDF sınıfını genişleten sınıf, eksik olan işlemi sağlar.
  • 🔢 Özel işlevin üç şekli: UDF her satır için tek bir sonuç döndürür, UDAF birçok satırı tek bir satıra indirger ve UDTF bir satırı birçok satıra genişletir.
  • Kayıt işlemi iki adımda tamamlanıyor: ADD JAR komutu kodu classpath'e ekler ve CREATE TEMPORARY FUNCTION komutu bir adı sınıfa bağlar.
  • ♻️ Burada önemli olan yeniden kullanımdır: Kök bulma fonksiyonu gibi test edilmiş bir kullanıcı tanımlı fonksiyon, her sorgudan yeniden yazılmak yerine çağrılabilir.

Hive Fonksiyonları: Dahili ve Kullanıcı Tanımlı Fonksiyonlar

Fonksiyonlar, tablo sütun adlarının işlenenleri üzerinde matematiksel, aritmetik, mantıksal ve ilişkisel işlemler gibi işlemleri gerçekleştirmek için belirli bir amaç doğrultusunda oluşturulur.

Yerleşik İşlevler

Bunlar Hive'da zaten mevcut olan işlevlerdir. Öncelikle uygulama gereksinimini kontrol etmemiz gerekiyor, ardından bu yerleşik işlevleri uygulamalarımızda kullanabiliriz. Bu fonksiyonları doğrudan uygulamamız içerisinde çağırabiliriz.

Sözdizimi ve türleri aşağıdaki bölümde belirtilmiştir.

Hive'da bulunan yerleşik fonksiyon türleri:

  • Toplama İşlevleri
  • Tarih Fonksiyonları
  • Matematiksel Fonksiyonlar
  • Koşullu Fonksiyonlar
  • Dize İşlevleri
  • Çeşitli Fonksiyonlar

Aşağıda altı ailenin her biri, fonksiyon imzaları ve dönüş tipleriyle birlikte açıklanmıştır.

Toplama İşlevleri

Bu fonksiyonlar koleksiyonlar için kullanılır. Koleksiyonlar, gruplar anlamına gelir.ping Bu fonksiyonlar, elemanlardan oluşan bir dizi döndürür ve fonksiyon adında belirtilen dönüş türüne bağlı olarak tek bir eleman veya elemanlardan oluşan bir dizi döndürür.

Dönüş Tipi Fonksiyon adı Açıklama
INT boyut (Harita ) Bu komut, harita türündeki bileşenlerin sayısını alacak ve verecektir.
INT boyut(Dizi ) Bu, dizi türündeki öğelerin sayısını alacak ve verecektir.
Sıralamak harita_anahtarları(Harita) ) Bu komut, girdi haritasının anahtarlarını içeren bir diziyi alıp verecektir. Dizi sıralı değildir.
Sıralamak harita_değerleri(Harita) ) Bu komut, girdi haritasının değerlerini içeren bir diziyi alacak ve verecektir. Dizi sıralı değildir.
Sıralamak sort_array(Dizi) ) Girdi dizisini elemanlarının artan sırasına göre sıralar ve döndürür.
Boole dizi_içerir(Dizi) , değer) Dizinin ikinci argüman olarak geçirilen değeri içerip içermediğini kontrol eder ve içeriyorsa TRUE değerini döndürür.

Tarih Fonksiyonları

Bunlar, tarih işlemleri gerçekleştirmek ve tarih türlerini bir türden diğerine dönüştürmek için kullanılır:

Fonksiyon adı Dönüş Tipi Açıklama
unix_zamandamgası() BigInt Akımı alacağız. Unix Saniye cinsinden zaman damgası. Değer, tüm sorgu için sabit değildir.
to_date(string timestamp) tarih Bu, zaman damgası dizesinin tarih bölümünü alacak ve size verecektir.
yıl(dize tarihi) INT Bir tarihin veya zaman damgası dizisinin yıl kısmını alıp verecek
çeyrek(tarih/zaman damgası/dize) INT 1 ila 4 aralığında bir tarih, zaman damgası veya dize için yılın çeyreğini alıp verecektir
ay(dize tarihi) INT Bir tarihin veya zaman damgası dizisinin ay kısmını verecektir
saat(dize tarihi) INT Zaman damgasının saatini alacak ve verecektir.
dakika(dize tarihi) INT Zaman damgasının dakikasını alacak ve verecektir.
tarih_alt(başlangıç ​​tarihi dizesi, gün sayısı tamsayısı) tarih Bu, alt işlemin sonucunu alacak ve verecektir.tracbaşlangıç ​​tarihinden itibaren birkaç gün
mevcut tarih tarih Sorgu değerlendirmesinin başlangıcında geçerli tarihi alacak ve verecektir.
son_gün(string tarih) dizi Bu komut, belirtilen tarihin ait olduğu ayın son gününü getirip verecektir.
trunc(dize tarihi, dize biçimi) dizi Belirtilen formatta yuvarlanmış tarihi alacak ve size verecektir. Desteklenen formatlar: AY/PZT/AA, YIL/YYYY/YY.

Matematiksel Fonksiyonlar

Bu fonksiyonlar matematiksel işlemler için kullanılır. Kullanıcı tanımlı fonksiyonlar (UDF'ler) oluşturmak yerine, Hive'da yerleşik bazı matematiksel fonksiyonlarımız mevcuttur.

Fonksiyon adı Dönüş Tipi Açıklama
yuvarlak(ÇİFT X) ÇİFT X'in yuvarlanmış BIGINT değerini alacak ve döndürecektir.
yuvarlak(ÇİFT X, INT d) ÇİFT X değerini d ondalık basamağa yuvarlayarak alacak ve geri döndürecektir.
sınır(ÇİFT X) ÇİFT Bu fonksiyon, bankacı yuvarlaması olarak da bilinen HALF_EVEN yuvarlama modunu kullanarak X'in yuvarlanmış BIGINT değerini alacak ve döndürecektir.
kat(ÇİFT X) BÜYÜK X değerine eşit veya ondan küçük olan en büyük BIGINT değerini alıp döndürecektir.
tavan(ÇİFT a), tavan(ÇİFT a) BÜYÜK Bu fonksiyon, a değerine eşit veya ondan büyük olan en küçük BIGINT değerini alır ve döndürür.
rand(), rand(INT tohumu) ÇİFT Bu fonksiyon, 0 ile 1 arasında düzgün dağılımlı rastgele bir sayı alıp döndürür. Bir tohum değeri (seed) verilmesi, dizinin tekrarlanabilir olmasını sağlar.

Koşullu Fonksiyonlar

Bu fonksiyonlar koşullu değer kontrolleri için kullanılır.

Fonksiyon adı Dönüş Tipi Açıklama
if(Boolean testCondition, T valueTrue, T valueFalseOrNull) T testCondition doğru olduğunda valueTrue, aksi durumda valueFalseOrNull değerini döndürecektir.
boş(X) Boole X NULL ise true, aksi halde false değerini döndürecektir.
boş değil(X) Boole X NULL değilse true, aksi takdirde false değerini döndürecektir.
nvl(T değeri, T varsayılan_değeri) T Değer NULL olduğunda default_value, aksi durumda ise value değerini döndürecektir.

Dize İşlevleri

Dize manipülasyonları ve dize işlemleri aşağıdaki fonksiyonlar tarafından gerçekleştirilir.

Fonksiyon adı Dönüş Tipi Açıklama
ters çevir(dize X) dizi X'in ters dizisini verecektir
rpad(string str, int uzunluk, string pad) dizi Toplam uzunluğu belirtilen uzunlukta, dolgu malzemesiyle desteklenmiş, doğru uzunlukta bir malzeme alacak ve verecektir.
rtrim(dize X) dizi X dizisinin sonundaki (sağ tarafındaki) boşlukları kırparak elde edilen dizeyi alacak ve döndürecektir.
Örneğin, rtrim('sonuçlar') 'sonuçlar' ile sonuçlanır
boşluk(INT n) dizi Bu, n adet boşluktan oluşan bir dizeyi alıp verecektir.
split(STRING str, STRING pat) dizi str'yi pat etrafında böler (pat bir düzenli ifadedir).
str_to_map(text[, delimiter1, delimiter2]) harita Bu, metni iki ayırıcı kullanarak anahtar-değer çiftlerine ayıracaktır. Ayırıcı 1 çiftleri ayırır ve ayırıcı 2 her çifti böler.

Çeşitli Fonksiyonlar

Yukarıdaki ailelerin hiçbirine ait olmayan birkaç yerleşik işlev bulunmaktadır. Bunlar arasında karma algoritmaları, oturum bilgileri ve rastgele fonksiyon çağırma yer almaktadır. Java yöntemleri.

Fonksiyon adı Dönüş Tipi Açıklama
karma(a1[, a2…]) INT Argümanların karma değerini döndürür.
mevcut_kullanıcı() dizi Yapılandırılmış kimlik doğrulama yöneticisinden geçerli kullanıcı adını döndürür.
mevcut_veritabanı() dizi Geçerli veritabanının adını döndürür.
md5 (dize/ikili) dizi MD5 128 bitlik sağlama toplamını 32 onaltılık basamaktan oluşan bir dize olarak döndürür veya boş bir argüman için NULL döndürür.
sha1 (dize/ikili) dizi Argümanın SHA-1 özetini onaltılık dize olarak döndürür.
crc32(dize/ikili) BigInt Dize veya ikili argümanın döngüsel yedeklilik kontrol değerini döndürür.
sürüm() dizi Hive sürümünü, derleme numarası ve ardından derleme karması olarak döndürür.
yansıt(sınıf, metot[, argüman1…]) değişir Çağrılar Java Yansıma (reflection) kullanarak argüman imzasını eşleştirerek yöntemi kullanır. `java_method()` bunun eş anlamlısıdır.

UDF'ler (Kullanıcı Tanımlı İşlevler)

Hive'da kullanıcılar, belirli müşteri gereksinimlerini karşılamak için kendi fonksiyonlarını tanımlayabilirler. Bunlar Hive'da UDF olarak bilinir. Kullanıcı tanımlı fonksiyonlar şu şekilde yazılır: Java belirli modüller için.

Bazı kullanıcı tanımlı fonksiyonlar (UDF'ler), uygulama çerçevelerinde kodun yeniden kullanılabilirliği için özel olarak tasarlanmıştır. Geliştirici bu fonksiyonları şu şekilde yazar: Java ve bu UDF'leri Hive ile entegre eder.

Sorgu yürütme sırasında geliştirici doğrudan kodu kullanabilir ve UDF'ler kullanıcı tanımlı görevlere göre çıktılar döndürür. Bu, kodlama ve yürütme açısından yüksek performans sağlar.

Örneğin, dize kök bulma işlemi için Hive'da önceden tanımlanmış bir fonksiyonumuz yok. Bunun için, bir kök bulma kullanıcı tanımlı fonksiyonu (UDF) yazabiliriz. JavaKök fonksiyona ihtiyaç duyduğumuz her yerde, bu kök UDF'yi Hive'da doğrudan çağırabiliriz.

Burada kök kelime işlevi, kelimeleri kök kelimelerinden türetmek anlamına gelir. Bir kök bulma algoritması, "wishing", "wished" ve "wishes" kelimelerini "wish" kök kelimesine indirger. Bu tür bir işlevi gerçekleştirmek için, bir UDF yazabiliriz. Java ve onunla entegre edin kovan.

Kullanım senaryosuna bağlı olarak, UDF farklı sayıda girdi ve çıktı değeri kabul edecek ve üretecek şekilde yazılabilir.

Genel olarak, kullanıcı tanımlı fonksiyon (UDF) tek bir giriş değeri alır ve tek bir çıkış değeri üretir. UDF bir sorguda kullanılırsa, sonuç veri kümesindeki her satır için bir kez çağrılır.

Diğer yönde ise, bir fonksiyon girdi olarak bir değer grubu alabilir ve tek bir çıktı değeri döndürebilir. Bu fark, aşağıda açıklanan üç özel fonksiyon türünü birbirinden ayıran şeydir.

Hive'da UDF, UDAF ve UDTF Karşılaştırması

Hive'daki özel fonksiyonlar, giren ve çıkan satır sayısına göre gruplandırılır. Yanlış tür seçimi, özel bir fonksiyonun derlenmeyi reddetmesinin veya tablo beklenirken tek bir satır döndürmesinin en yaygın nedenidir.

Menşei Gelen satırlar → giden satırlar Sınıfı uzatmak Dahili örnekler
UDF Bir sıra → bir sıra org.apache.hadoop.hive.ql.exec.UDF uzunluk(), yuvarlama(), ters çevirme()
UDAF Birçok satır → tek satır org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolver sayma(), minimum(), maksimum()
UDTF Tek satır → birçok satır org.apache.hadoop.hive.ql.udf.generic.GenericUDTF explode(), json_tuple(), parse_url_tuple()

Tablodan iki pratik kural çıkarılabilir:

  • UDAF ifadesi neredeyse her zaman GROUP BY yan tümcesiyle birlikte kullanılır, çünkü her grubu tek bir satıra indirger.
  • Bir UDTF, aynı SELECT listesinde diğer sütunlarla birlikte seçilemez, bu nedenle genellikle LATERAL VIEW ile birlikte kullanılır.

Satır düzeyinde çalışma için daha yetenekli ikinci bir temel sınıf da mevcuttur: GenericUDF. Bu sınıf, diziler, haritalar ve yapılar gibi karmaşık türleri ve değişken sayıda argümanı kabul eder.

Hive'da Kullanıcı Tanımlı Fonksiyon (UDF) Nasıl Yazılır ve Kaydedilir?

Yukarıda açıklanan örnek, dört adımda gerçek bir fonksiyon olarak oluşturulabilir. Bunun ötesinde hiçbir şey gerekmez. Java Derleyici ve çalışan bir Hive oturumu gereklidir.

) 1 Adım Yaz Java UDF'den türeyen ve herkese açık bir evaluate() metodu uygulayan bir sınıf. Hive, evaluate() metodunu her satır için bir kez çağırır, bu nedenle metot NULL girdisini de ele almalıdır.

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);
    }
}

) 2 Adım Sınıfı derleyin ve örneğin hive-udf-1.0.jar gibi bir JAR dosyasına, bağımlı olduğu tüm sınıflarla birlikte paketleyin.

) 3 Adım JAR dosyasını Hive sınıf yoluna ekleyin ve bir fonksiyon adını sınıfa bağlayın. Geçici bir fonksiyon yalnızca geçerli oturum boyunca yaşar.

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

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

) 4 Adım Yeni fonksiyonu tıpkı yerleşik bir fonksiyon gibi çağırın. "Dilemek", "dilenmiş" ve "dilekler" kelimelerine uygulandığında, bu sınıf her üçü için de "dilemek" değerini döndürür.

SELECT word, stem(word) FROM words;

İşlevin her oturum ve her kullanıcı için kullanılabilir olmasını sağlamak için, onu kalıcı olarak bir veritabanına kaydedin. JAR dosyası, tüm kümenin okuyabileceği bir yolda bulunmalıdır; bu genellikle HDFS anlamına gelir.

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

Tek bir sınıf birden fazla evaluate() metodu tanımlayabilir. Hive, çağrıyı argüman imzalarıyla eşleştirir; bu sayede bir fonksiyon hem dize hem de tamsayı kabul edebilir.

SSS

SHOW FUNCTIONS komutu, özel olanlar da dahil olmak üzere kayıtlı tüm adları listeler. DESCRIBE FUNCTION name komutu tek satırlık bir imza yazdırır ve DESCRIBE FUNCTION EXTENDED name komutu, uygulayan sınıfın sağladığı durumlarda kullanım örnekleri ekler.

Neredeyse her zaman bir isim veya kapsam sorunudur: AS'den sonraki dize, tam nitelikli sınıf adı olmalıdır ve ADD JAR yalnızca çalıştırıldığı oturum için geçerlidir. Yeniden bağlanmak hem JAR dosyasını hem de geçici işlevleri siler.

Fonksiyon, diziler, haritalar veya yapılar gibi karmaşık türler alıyorsa, değişken sayıda argüman içeriyorsa veya argüman türlerini kendisi doğrulaması gerekiyorsa GenericUDF kullanın. Basit UDF sınıfı, türleri yansıma yoluyla çözümler ve yalnızca temel Writable'ları işler.

Gerçek bir UDF (Kullanıcı Tanımlı Fonksiyon) JVM üzerinde çalışmalıdır. Diğer diller için, kovan TRANSFORM yan tümcesini sunar; bu yan tümce, her satırı harici bir komut dosyası üzerinden geçirir. Python Standart giriş ve çıkışa göre daha yavaştır ancak standart giriş ve çıkıştan kaçınır. Daha yavaştır ancak olası sorunları önler. Java Baştan sona.

Yapabilirler. evaluate() fonksiyonu her satır için bir kez çalışır, bu nedenle maliyetli mantık satır sayısıyla çarpılır ve metodun içindeki nesne tahsisi çöp toplama baskısını artırır. Mümkünse yerleşik bir fonksiyon tercih edin ve evaluate() fonksiyonunu G/Ç'den uzak tutun.

Hayır. Fonksiyon adları büyük/küçük harf duyarlılığı olmadan çözümlenir, bu nedenle ROUND(), Round() ve round() aynı fonksiyondur. Java AS yan tümcesindeki sınıf adı farklı bir konudur ve derlenmiş sınıfla, paketi de dahil olmak üzere, birebir aynı olmalıdır.

Makine öğrenimi yardımcıları, düz dil açıklamalarını aday imzalara eşler ve dönüş türünün hedef sütuna uymayacağı durumlarda uyarı verir. Oluşturulan adlar bazen başka bir SQL lehçesine ait olabileceğinden, öneriyi belgelenmiş imzayla doğrulayın.

Bu, işlemi açıklayan bir yorumdan kullanılabilir bir iskelet (sınıf bildirimi, içe aktarmalar ve bir evaluate() metodu) oluşturur. Null değer işleme, yazılabilir tipler ve paketleme adımı hala gözden geçirilmeye ihtiyaç duyuyor ve fonksiyon gerçek satırlarda test edilmelidir.

Bu yazıyı şu şekilde özetleyin: