Hive関数:組み込み関数とUDF(ユーザー定義関数)の例

⚡ スマートサマリー

Hive 関数は 2 つのグループに分類されます。エンジンに付属する組み込み関数で、コレクション、日付、数学、条件、文字列、その他の作業をカバーします。ユーザー定義関数は、 Java Hiveが提供しないロジックについて。

  • 📚 6つの組み込み型ファミリー: コレクション関数、日付関数、数学関数、条件関数、文字列関数、その他の関数は、HiveQL内で直接呼び出すことができます。
  • 🧾 署名は重要です。 すべての関数には固定の引数リストと文書化された戻り値の型があり、戻り値の型によってその関数がどこで使用できるかが決まります。
  • 🧩 UDFは不足部分を補う: 組み込み関数が存在しない場合、 Java org.apache.hadoop.hive.ql.exec.UDF を拡張するクラスは、不足している操作を提供します。
  • 🔢 カスタム機能の3つの形状: UDFは行ごとに1行を返し、UDAFは複数の行を1行にまとめ、UDTFは1行を複数の行に展開します。
  • 🛠️ 登録は2ステップで完了します。 ADD JAR はコードをクラスパスに配置し、CREATE TEMPORARY FUNCTION はクラスに名前をバインドします。
  • ♻️ 再利用こそが重要な点だ。 ステマーなどのテスト済みのUDFは、クエリごとに書き直すのではなく、すべてのクエリから呼び出すことができます。

Hive関数:組み込み関数とユーザー定義関数

関数は、テーブルの列名をオペランドとして、数学演算、算術演算、論理演算、関係演算などの操作を実行するという特定の目的のために構築されます。

組み込み関数

これらは、Hive ですでに利用可能な関数です。 まず、アプリケーションの要件を確認する必要があります。その後、これらの組み込み関数をアプリケーションで使用できるようになります。 これらの関数をアプリケーション内で直接呼び出すことができます。

構文と型については次のセクションで説明します。

Hiveの組み込み関数の種類:

  • 収集関数
  • 日付関数
  • 数学関数
  • 条件関数
  • 文字列関数
  • その他機能

以下では、6つのファミリーそれぞれについて、関数シグネチャと戻り値の型とともに説明します。

収集関数

これらの関数はコレクションに使用されます。コレクションとは、グループを意味します。ping 要素の集合であり、関数名で指定されている戻り値の型に応じて、単一の要素または要素の配列を返します。

戻り値の型 関数名 詳細説明
INT サイズ(地図) マップタイプのコンポーネントの数を取得して表示します
INT サイズ(配列) 配列型の要素数を取得して表示します
配列 map_keys(マップ) 入力マップのキーを含む配列を取得して返します。配列は順不同です。
配列 map_values(マップ) ) 入力マップの値を含む配列を取得して返します。配列は順不同です。
配列 sort_array(配列) ) 入力配列を要素の昇順にソートして返します。
ブーリアン array_contains(Array 、 価値) 配列に2番目の引数として渡された値が含まれている場合はTRUEを返します。

日付関数

これらは、日付の操作や、ある日付型から別の日付型への変換を行うために使用されます。

関数名 戻り値の型 詳細説明
unix_timestamp() BigInt 私たちは現在 Unixの タイムスタンプ(秒単位)。クエリ全体を通して値は固定されません。
to_date(文字列タイムスタンプ) date タイムスタンプ文字列から日付部分を取得して返します。
年(文字列日付) INT 日付またはタイムスタンプ文字列の年の部分を取得して提供します。
四半期(日付/タイムスタンプ/文字列) INT 日付、タイムスタンプ、または 1 ~ 4 の範囲の文字列を取得して、年の四半期を返します。
月(文字列日付) INT 日付またはタイムスタンプ文字列の月の部分を与えます。
時(文字列日付) INT タイムスタンプの時刻を取得して表示します
分(文字列日付) INT タイムスタンプの分を取得して表示します
date_sub(string 開始日, int 日数) date サブの結果を取得して表示しますtrac開始日から数日後
現在の日付 date クエリ評価の開始時に現在の日付を取得して表示します。
last_day(文字列日付) string 指定された日付が属する月の最終日を取得して表示します。
trunc(日付文字列、文字列形式) string 指定されたフォーマットで指定された単位に切り捨てられた日付を取得して表示します。 サポートされるフォーマット: 月/月/MM、年/YYYY/YY。

数学関数

これらの関数は数学演算に使用されます。UDFを作成する代わりに、Hiveにはいくつかの組み込み数学関数が用意されています。

関数名 戻り値の型 詳細説明
ラウンド(ダブルエックス) ダブル Xの丸められたBIGINT値を取得して返します
ラウンド(DOUBLE X, INT d) ダブル X を小数点以下 d 桁に丸めて取得し返します
ブラウン(ダブルエックス) ダブル これは、HALF_EVEN丸めモード(銀行丸めとも呼ばれる)を使用して、Xの丸められたBIGINT値を取得して返します。
フロア(ダブルエックス) BIGINT X値以下の最大のBIGINT値を取得して返します。
ceil(DOUBLE a)、ceiling(DOUBLE a) BIGINT a の値以上の最小の BIGINT 値を取得して返します
rand()、rand(INTシード) ダブル 0から1までの範囲で一様に分布する乱数を取得して返します。シードを指定すると、シーケンスが再現可能になります。

条件関数

これらの関数は、条件付き値のチェックに使用されます。

関数名 戻り値の型 詳細説明
if(Boolean testCondition, T valueTrue, T valueFalseOrNull) T testConditionが真の場合はvalueTrueを返し、それ以外の場合はvalueFalseOrNullを返します。
isnull(X) ブーリアン XがNULLの場合はtrueを、それ以外の場合はfalseを取得します。
isnotnull(X) ブーリアン XがNULLでない場合はtrueを、それ以外の場合はfalseを取得します。
nvl(T value, T default_value) T 値がNULLの場合はdefault_valueが、それ以外の場合はvalueが返されます。

文字列関数

文字列の操作および文字列演算は、以下の関数によって処理されます。

関数名 戻り値の型 詳細説明
逆順(文字列X) string Xの反転文字列が得られます
rpad(文字列 str, int 長, 文字列パッド) string これは文字列を取得し、パディングで右にパディングして、合計の長さが長さになるようにします。
rtrim(文字列 X) string これは、X の末尾 (右側) から空白を削除した結果の文字列を取得して返します。
例えば、、rtrim(' 結果 ') の結果は '結果'
スペース(INT n) string これはn個の空白文字からなる文字列を取得して出力します。
split(STRING str, STRING pat) 配列 pat の周囲で str を分割します (pat は正規表現です)。
str_to_map(text[, delimiter1, delimiter2]) 地図 この機能は、2つの区切り文字を使用してテキストをキーと値のペアに分割します。区切り文字1はペアを区切り、区切り文字2は各ペアを分割します。

その他機能

いくつかの組み込み関数は、上記のどのファミリーにも属しません。これらには、ハッシュ、セッション情報、任意の呼び出しが含まれます。 Java 方法。

関数名 戻り値の型 詳細説明
hash(a1[, a2…]) INT 引数のハッシュ値を返します
現在のユーザー() string 設定済みの認証マネージャーから現在のユーザー名を返します。
現在のデータベース() string 現在のデータベースの名前を返します
MD5(文字列/バイナリ) string 128ビットMD5チェックサムを32桁の16進数文字列として返します。引数がNULLの場合はNULLを返します。
sha1(文字列/バイナリ) string 引数のSHA-1ダイジェストを16進数文字列として返します。
crc32(文字列/バイナリ) BigInt 文字列またはバイナリ引数の巡回冗長検査値を返します。
バージョン() string Hiveのバージョンをビルド番号とビルドハッシュの形式で返します。
reflect(class, method[, arg1…]) 変化する コール Java リフレクションを使用して引数シグネチャを照合することでメソッドを取得します。java_method() は同義語です。

UDF (ユーザー定義関数)

Hiveでは、ユーザーは特定のクライアント要件を満たす独自の関数を定義できます。これらはHiveではUDFと呼ばれます。ユーザー定義関数は次のように記述されます。 Java 特定のモジュール用。

一部のUDFは、アプリケーションフレームワークでのコードの再利用性を目的として特別に設計されています。開発者はこれらの関数を次のように記述します。 Java そして、それらのUDFをHiveと統合します。

クエリ実行時、開発者はコードを直接使用でき、UDFはユーザー定義のタスクに従って出力を返します。これにより、コーディングと実行の両面で高いパフォーマンスを実現します。

例えば、文字列のステミングに関しては、Hiveには事前定義された関数はありません。そのため、ステミングUDFを記述することができます。 Javaステム機能が必要な場所ではどこでも、Hive 内でこのステム UDF を直接呼び出すことができます。

ここで語幹機能とは、語根から単語を派生させることを意味します。語幹抽出アルゴリズムは、「wishing」、「wished」、「wishes」という単語を語根「wish」に還元します。このタイプの機能を実行するには、UDF を記述できます。 Java そしてそれを統合する ハイブ.

使用事例に応じて、UDFは異なる数の入力値と出力値を受け入れ、生成するように記述できます。

一般的なUDF(ユーザー定義関数)は、単一の入力値を受け取り、単一の出力値を生成します。UDFがクエリ内で使用される場合、結果データセットの各行に対してUDFが一度呼び出されます。

逆に、関数は入力として複数の値を受け取り、単一の出力値を返すこともできます。この違いこそが、次に説明する3種類のカスタム関数を区別するものです。

HiveにおけるUDF、UDAF、UDTFの違い

Hiveのカスタム関数は、入力される行数と出力される行数によって分類されます。型の選択を誤ると、カスタム関数がコンパイルに失敗したり、テーブルが期待される箇所で単一行が返されたりする最も一般的な原因となります。

タイプ 入力行数 → 出力行数 拡張するクラス 組み込みの例
UDF 1行 → 1行 org.apache.hadoop.hive.ql.exec.UDF length()、round()、reverse()
UDAF 多数の行 → 1行 org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolver count()、min()、max()
UDTF 1行 → 複数行 org.apache.hadoop.hive.ql.udf.generic.GenericUDTF explode()、json_tuple()、parse_url_tuple()

この表から、以下の2つの実用的なルールが導き出されます。

  • UDAFは、各グループを1行に集約するため、ほぼ必ずGROUP BY句と組み合わせて使用​​されます。
  • UDTFは同じSELECTリスト内の他の列と同時に選択することはできないため、通常はLATERAL VIEWと組み合わせて使用​​されます。

また、行レベルの処理には、より高機能な基底クラスであるGenericUDFも用意されており、配列、マップ、構造体などの複雑な型や、可変個の引数を受け入れることができます。

HiveでUDFを記述および登録する方法

上記のステムの例は、4 つのステップで実際の関数として構築できます。 Java コンパイラと実行中のHiveセッションが必要です。

ステップ1) 書く Java UDFを継承し、パブリックなevaluate()メソッドを実装するクラス。Hiveはevaluate()メソッドを1行につき1回呼び出すため、このメソッドは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);
    }
}

ステップ2) クラスをコンパイルし、依存するクラスとともに、例えば hive-udf-1.0.jar のような JAR ファイルにパッケージ化します。

ステップ3) JARファイルをHiveのクラスパスに配置し、関数名をクラスにバインドしてください。一時関数は現在のセッションのみ有効です。

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

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

ステップ4) 新しい関数は、組み込み関数とまったく同じように呼び出します。「wishing」、「wished」、「wishes」という単語にこのクラスを適用すると、3つすべてに対して「wish」が返されます。

SELECT word, stem(word) FROM words;

この機能のすべてのセッションとすべてのユーザーが利用できるようにするには、データベースに永続的に登録してください。JARファイルは、クラスタ全体が読み取れるパスに配置する必要があり、通常はHDFSが該当します。

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

1つのクラスで複数の evaluate() メソッドを宣言できます。Hive は呼び出しを引数のシグネチャと照合するため、1 つの関数で文字列と整数の両方を受け入れることができます。

よくあるご質問

SHOW FUNCTIONS は、カスタム名を含む登録済みのすべての名前を一覧表示します。DESCRIBE FUNCTION name は 1 行のシグネチャを出力し、DESCRIBE FUNCTION EXTENDED name は、実装クラスが提供する使用例を追加します。

ほとんどの場合、名前またはスコープの問題です。AS の後の文字列は完全修飾クラス名である必要があり、ADD JAR は実行したセッションにのみ適用されます。再接続すると、JAR ファイルと一時関数が両方とも削除されます。

関数が配列、マップ、構造体などの複雑な型、可変個の引数を受け取る場合、または引数の型を自身で検証する必要がある場合は、GenericUDF を使用してください。シンプルな UDF クラスはリフレクションによって型を解決し、プリミティブな Writable のみを扱います。

真のUDFはJVM上で実行されなければなりません。他の言語の場合、 ハイブ TRANSFORM句を使用すると、各行を外部スクリプトにストリーミングできます。 Python 標準入出力よりも遅いですが、 Java 完全に。

可能です。evaluate() は行ごとに一度実行されるため、高負荷なロジックが行数に応じて増加し、メソッド内のオブジェクト割り当てによってガベージコレクションの負荷が増大します。組み込み関数が存在する場合はそちらを使用し、evaluate() は入出力処理を行わないようにしてください。

いいえ。関数名は大文字小文字を区別せずに解決されるため、ROUND()、Round()、round() は同じ関数です。 Java AS句におけるクラス名は別問題であり、コンパイルされたクラス名(パッケージ名を含む)と完全に一致する必要があります。

機械学習アシスタントは、平易な言語による説明を候補となるシグネチャにマッピングし、戻り値の型がターゲット列に適合しない場合に警告を発します。生成された名前が別のSQL方言に属する場合があるため、提案内容を文書化されたシグネチャと照合して確認してください。

この機能は、操作内容を記述したコメントから、クラス宣言、インポート、evaluate() メソッドといった使用可能なスケルトンを生成します。ただし、null 処理、Writable 型、パッケージング手順については引き続き検討が必要であり、実際の行データを用いて機能をテストする必要があります。