Hive自定义函数
当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined function)。 Hive目前只支持用java语言书写自定义函数。如果需要采用其他语言,比如Python,可以考虑上一节提到的transform语法来实现。 Hive支持三
当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined function)。
Hive目前只支持用java语言书写自定义函数。如果需要采用其他语言,比如Python,可以考虑上一节提到的transform语法来实现。
Hive支持三种自定义函数,我们逐个讲解。
UDF
这是普通的用户自定义函数。接受单行输入,并产生单行输出。
编写java代码如下:
package com.oserp.hiveudf;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public classPassExam extendsUDF {
publicText evaluate(Integer score)
{
Text result = new Text();
if(score
result.set("Failed");
else
result.set("Pass");
return result;
}
}
然后,打包成.jar文件,比如hiveudf.jar。
执行以下语句:
add jar /home/user/hadoop_jar/hiveudf.jar;
create temporary function pass_scorecom.oserp.hiveudf.PassExam;
select stuNo,pass_score(score) from student;
输出结果为:
N0101 Pass
N0102 Failed
N0201 Pass
N0103 Pass
N0302 Pass
N0202 Pass
N0203 Pass
N0301 Failed
N0306 Pass
第一个语句注册jar文件;第二个语句为自定义函数取别名;第三个语句调用自定义函数。
Java代码中,自定义函数的类继承自UDF类,且提供了一个evaluate方法。这个方法接受一个整数值作为参数,并返回字符串。结构十分明了。其中的evaluate方法并没有作为interface提供,因为实际使用时,函数的参数个数及类型是多变的。
以上UDF名称是不区分大小写的,比如调用时写成PASS_SCORE也是可以的(因为它是hive中的别名,不是java类名)。
使用完成后,可调用以下语句删除函数别名:
Drop temporary function pass_score;
UDAF
用户定义聚集函数(User-defined aggregate function)。接受多行输入,并产生单行输出。比如MAX,COUNT函数。
编写以下Java代码:
packagecom.oserp.hiveudf;
importorg.apache.hadoop.hive.ql.exec.UDAF;
importorg.apache.hadoop.hive.ql.exec.UDAFEvaluator;
importorg.apache.hadoop.hive.serde2.io.DoubleWritable;
importorg.apache.hadoop.io.IntWritable;
publicclass HiveAvgextends UDAF {
public staticclass AvgEvaluate implements UDAFEvaluator
{
public staticclass PartialResult
{
public intcount;
public doubletotal;
public PartialResult()
{
count = 0;
total = 0;
}
}
private PartialResultpartialResult;
@Override
public voidinit() {
partialResult = new PartialResult();
}
public booleaniterate(IntWritable value)
{
// 此处一定要判断partialResult是否为空,否则会报错
// 原因就是init函数只会被调用一遍,不会为每个部分聚集操作去做初始化
//此处如果不加判断就会出错
if (partialResult==null)
{
partialResult =new PartialResult();
}
if (value !=null)
{
partialResult.total =partialResult.total +value.get();
partialResult.count=partialResult.count + 1;
}
return true;
}
public PartialResult terminatePartial()
{
returnpartialResult;
}
public booleanmerge(PartialResult other)
{
partialResult.total=partialResult.total + other.total;
partialResult.count=partialResult.count + other.count;
return true;
}
public DoubleWritable terminate()
{
return newDoubleWritable(partialResult.total /partialResult.count);
}
}
}
然后打包成jar文件,比如hiveudf.jar。
执行以下语句:
add jar/home/user/hadoop_jar/hiveudf.jar;
create temporary function avg_udf as'com.oserp.hiveudf.HiveAvg';
select classNo, avg_udf(score) from studentgroup by classNo;
输出结果如下:
C01 68.66666666666667
C02 80.66666666666667
C03 73.33333333333333
参照以上图示(来自Hadoop权威教程)我们来看看各个函数:
l Init在类似于构造函数,用于UDF的初始化。
注意上图中红色框中的init函数。在实际运行中,无论hive将记录集划分了多少个部分去做(比如上图中的file1和file2两个部分),init函数仅被调用一次。所以上图中的示例是有歧义的。这也是为什么上面的代码中加了特别的注释来说明。或者换一句话说,init函数中不应该用于初始化部分聚集值相关的逻辑,而应该处理全局的一些数据逻辑。
l Iterate函数用于聚合。当每一个新的值被聚合时,此函数被调用。
l TerminatePartial函数在部分聚合完成后被调用。当hive希望得到部分记录的聚合结果时,此函数被调用。
l Merge函数用于合并先前得到的部分聚合结果(也可以理解为分块记录的聚合结果)。
l Terminate返回最终的聚合结果。
我们可以看出merge的输入参数类型和terminatePartial函数的返回值类型必须是一致的。
UDTF
用户定义表生成函数(User-defined table-generating function)。接受单行输入,并产生多行输出(即一个表)。不是特别常用,此处不详述。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Go 言語は、クロージャとリフレクションという 2 つの動的関数作成テクノロジを提供します。クロージャを使用すると、クロージャ スコープ内の変数にアクセスでき、リフレクションでは FuncOf 関数を使用して新しい関数を作成できます。これらのテクノロジーは、HTTP ルーターのカスタマイズ、高度にカスタマイズ可能なシステムの実装、プラグイン可能なコンポーネントの構築に役立ちます。

C++ 関数の名前付けでは、読みやすさを向上させ、エラーを減らし、リファクタリングを容易にするために、パラメーターの順序を考慮することが重要です。一般的なパラメータの順序規則には、アクション-オブジェクト、オブジェクト-アクション、意味論的な意味、および標準ライブラリへの準拠が含まれます。最適な順序は、関数の目的、パラメーターの種類、潜在的な混乱、および言語規約によって異なります。

効率的で保守しやすい Java 関数を作成するための鍵は、シンプルに保つことです。意味のある名前を付けてください。特殊な状況に対処します。適切な可視性を使用してください。

1. SUM 関数は、列またはセルのグループ内の数値を合計するために使用されます (例: =SUM(A1:J10))。 2. AVERAGE 関数は、列またはセルのグループ内の数値の平均を計算するために使用されます (例: =AVERAGE(A1:A10))。 3. COUNT 関数。列またはセルのグループ内の数値またはテキストの数をカウントするために使用されます。例: =COUNT(A1:A10)。 4. IF 関数。指定された条件に基づいて論理的な判断を行い、結果を返すために使用されます。対応する結果。

C++ 関数のデフォルト パラメーターの利点には、呼び出しの簡素化、可読性の向上、エラーの回避などがあります。欠点は、柔軟性が限られていることと、名前の制限があることです。可変引数パラメーターの利点には、無制限の柔軟性と動的バインディングが含まれます。欠点としては、複雑さの増大、暗黙的な型変換、デバッグの難しさなどが挙げられます。

C++ で参照型を返す関数の利点は次のとおりです。 パフォーマンスの向上: 参照による受け渡しによりオブジェクトのコピーが回避され、メモリと時間が節約されます。直接変更: 呼び出し元は、返された参照オブジェクトを再割り当てせずに直接変更できます。コードの簡素化: 参照渡しによりコードが簡素化され、追加の代入操作は必要ありません。

カスタム PHP 関数と定義済み関数の違いは次のとおりです。 スコープ: カスタム関数はその定義のスコープに限定されますが、事前定義関数はスクリプト全体からアクセスできます。定義方法: カスタム関数は function キーワードを使用して定義されますが、事前定義関数は PHP カーネルによって定義されます。パラメータの受け渡し: カスタム関数はパラメータを受け取りますが、事前定義された関数はパラメータを必要としない場合があります。拡張性: カスタム関数は必要に応じて作成できますが、事前定義された関数は組み込みで変更できません。

C++ の例外処理は、特定のエラー メッセージ、コンテキスト情報を提供し、エラーの種類に基づいてカスタム アクションを実行するカスタム例外クラスを通じて強化できます。 std::Exception から継承した例外クラスを定義して、特定のエラー情報を提供します。カスタム例外をスローするには、throw キーワードを使用します。 try-catch ブロックでdynamic_castを使用して、キャッチされた例外をカスタム例外タイプに変換します。実際の場合、open_file 関数は FileNotFoundException 例外をスローします。例外をキャッチして処理すると、より具体的なエラー メッセージが表示されます。
