Scalaのアプリケーション--UDF:ユーザー定義関数

Hadoopのは、IDAとのMavenプロジェクトを作成し、window10にインストールされています。

    <プロパティ> 
        <spark.version> 2.2.0 </spark.version> 
        <scala.version> 2.11 </scala.version> 
        <のjava.version> 1.8 </java.version> 
    </プロパティ> 

    <依存性> 
        <依存> 
            <のgroupId> org.apache.spark </のgroupId> 
            <たartifactId>火花コア_ $ {scala.version} </たartifactId> 
            <バージョン> $ {spark.version} </バージョン> 
        </依存> 
        <依存性> 
            < groupId> org.apache.spark </のgroupId> 
            <たartifactId>スパーク-SQL _ $ {scala.version} </たartifactId> 
            <バージョン> $ {スパーク。バージョン} </バージョン> 
        </依存> 
        <依存性> 
            <のgroupId> org.apache.spark </のgroupId> 
            <たartifactId>スパークストリーミング_ $ {scala.version} </たartifactId> 
            <バージョン> $ {spark.version} </バージョン> 
        </依存> 
        <依存性> 
            <のgroupId > org.apache.spark </のgroupId> 
            <たartifactId>火花糸_ $ {scala.version} </たartifactId> 
            <バージョン> $ {spark.version} </バージョン> 
        </依存> 

        <依存性> 
            <のgroupId>のMySQL </ groupIdを> 
            <たartifactId>のmysql-コネクタ-javaの</たartifactId> 
            <バージョン> 8.0.16 </バージョン> 
        </依存関係>
    </依存関係> 


    <ビルド>
        <finalName> learnspark </ finalName> finalName> learnspark </ finalName> 
        <プラグイン> 
            <プラグイン>
                <groupIdを> net.alchim31.maven </ groupIdを> 
                <たartifactId>スカラ-のMavenプラグイン- </たartifactId> 
                <バージョン> 3.2.2 </バージョン> 
                <実行> 
                    <実行> 
                        <目標> 
                            <目標>コンパイル</目標> 
                            <目標> testCompile </目標> 
                        </目標> 
                    </実行> 
                </実行> 
            </プラグイン> 
            <プラグイン> 
                <groupIdを> org.apache。maven.plugins </ groupIdを> 
                <たartifactId>のmaven-組立・プラグイン</たartifactId> 
                <バージョン> 3.0.0 </バージョン> 
                <設定>
                    <アーカイブ> 
                        <マニフェスト> 
                            <mainClass>学ぶ</ mainClass> 
                        </マニフェスト> 
                    </アーカイブ> 
                    <descriptorRefs> 
                        <descriptorRef>ジャーとの依存関係</ descriptorRef> 
                    </ descriptorRefs> 
                </ configuration>の
                <実行> 
                    <実行> 
                        <ID>メイクアセンブリ</ ID> 
                        <相>パッケージ</相> 
                        <目標>
                            <目標>シングル</目標>
                        </目標> 
                    </実行>
                </実行> 
            </プラグイン> 
        </プラグイン> 
    </ビルド>

  

データ準備:

{ "名前": "张3"、 "年齢":20} 
、{ "名前": "李4"、 "年齢":20}
、{ "名前": "王5"、 "年齢":20}
、{」名前":"赵6" 、 "年齢":20}
路径:
データ/入力/ユーザー/ user.json 
程序:
com.zouxxyy.spark.sqlパッケージ

インポートorg.apache.spark.SparkConf 
インポートorg.apache.spark.sql.expressions。{MutableAggregationBuffer、アグリゲータで、UserDefinedAggregateFunction} 
インポートorg.apache.spark.sql.types。{データ型、DoubleType、 LongType、StructType} 
インポート{org.apache.spark.sql列、データフレーム、データセット、エンコーダ、エンコーダ、ロウ、SparkSession、TypedColumn} 

/ ** 
 * UDF:ユーザ定義関数
 * / 

オブジェクト{UDF 

  DEFメイン(引数:配列[文字列]):単位= { 
    するSystem.setProperty( "hadoop.home.dir"、 "D:\\ gitworkplace \\ \\ winutilsのHadoop-2.7.1")
//これは、パスIのHadoopを指定するために使用されあなたのHadoop環境変数問題はない場合、あなたは書くことはできません
    SparkConf =新しいSparkConf(:ヴァルsparkConf )setMaster( "ローカル[*]")setAppName( "UDFを" ..) 

    // SparkSessionを作成します。
    スパークヴァル:SparkSession = SparkSession.builder.config(sparkConf).getOrCreate()

    インポートspark.implicits._ 

    // JSONデータフレームから読み込まれ得
    ヴァルフレーム:データフレーム= spark.read.json(「データ/ INPUT /ユーザー/user.json ")

    frame.createOrReplaceTempView("ユーザー")

    ://ケース私は、簡単な関数のテストカスタマイズ
    addName"、(X spark.udf.register( "名:=> String)を":「+ x)は、 

    。spark.sql( "ユーザーからaddName(名前)を選択")ショー()

    //ケースII:重合試験の種類のカスタム弱い機能

    ヴァルudaf1 =新しい新しいMyAgeAvgFunctionの

    spark.udf.register( "でAvgAge"、udaf1)

    スパーク。 SQL( "でAvgAge(年齢)を選択し 、ユーザーから")。ショー() 

    //ケース3:重合のカスタムタイプの強力な機能テスト

    ヴァルはudaf2 =新しい新しいMyAgeAvgClassFunction 

    重合列に//クエリ機能
    avgColヴァル:TypedColumn [UserBeanの、ダブル] = udaf2.toColumn.name( "aveAge")

    DSLスタイル強く型付けされたプログラミングの構文を使用して//データセット
    ヴァルuserDS:データセット[UserBeanの] = frame.as [UserBeanの] 

    userDS.select (avgCol).SHOW()

    spark.stop()
  } 
} 

/ ** 
 *機能ポリ(弱いタイプ)でカスタム
 * / 

クラスMyAgeAvgFunction UserDefinedAggregateFunctionを拡張{ 

  //入力データ構造
  オーバーライドDEF inputSchema:= {StructType 
    新しい新しいStructType( )( "年齢"、LongType).add 
  } 

  計算に//データ構造を
  オーバーライドDEF bufferSchemaを:= {StructType 
    新しい新しいStructType()を追加( "SUM"、LongType)が( "COUNT"、LongType)を.add。
  } 

  //関数によって返されるデータ型 
  オーバーライドをDEFデータ型:データ型= DoubleType
 
  //機能が安定し
  オーバーライドDETERMINISTIC DEF:trueに=ブールを

  前に初期化//計算用バッファ領域
  オーバーライド初期DEF(緩衝液:MutableAggregationBuffer):単位= { 
    //名前のない、唯一の構造
    バッファ(0) 0L = 
    (1)バッファ= 0L 
  } 

  //照会結果用キャッシュの更新に応じて
  オーバーライドDEF更新(バッファ:MutableAggregationBuffer、入力:行):単位= { 
    (0)= buffer.getLong(0)+入力バッファ。 GetLong(0)
    (1)、バッファ(1)buffer.getLong = + 1 
  } 

  複数のノードの//マージバッファ領域
  オーバーライドDEFマージ(バッファ1:MutableAggregationBuffer、バッファ2:行)単位= { 
    バッファ1(0)=バッファ1 .getLong(0)+ buffer2.getLong(0 )
    バッファ1(1)buffer1.getLong =(1)buffer2.getLong +(1)
  } 
 
  //バッファ内の計算ものは、最終的なリターン結果を与えます
  DEF評価オーバーライド(緩衝液:行):= {どれ
    buffer.getLong(0).toDouble / buffer.getLong(1)
  } 
} 


/ * * 
 *関数は、ポリ定義されているので(強いタイプ)
 * / 

ケースクラスUserBeanの(名前:文字列、年齢:BigInt型)//デフォルトのデジタルファイルはのBigInt読み
ケースクラスAvgBuffer(VARのSUM:BIGINT、VAR COUNT:INT)

クラスMyAgeAvgClassFunctionをでアグリゲータが延びる[UserBeanの、AvgBuffer、ダブル] { 

  //初期化バッファ
  オーバーライドDEF ZERO:= {AvgBuffer 
    AvgBuffer(0、0)
  } 

  //入力データと計算バッファ
  DEF低減オーバーライド(B:AvgBuffer、 :UserBeanのを)。 = {AvgBuffer 
    b.sum + = b.sum a.age 
    b.count = b.count +。1
    //返回B 
    B 
  } 
 
  マージ//バッファゾーン
  オーバーライドDEFマージ(B1:AvgBuffer、B2:AvgBuffer):AvgBuffer = { 
    b1.sum = b1.sum + b2.sum 
    b1.count = b1.count + b2.count 

    B1 
  } 

  //计算返回值
  オーバーライドDEF仕上げ(減少:AvgBuffer):ダブル= { 
    reduction.sum.toDouble / reduction.count 
  } 

  bufferEncoder DEFオーバーライド:エンコーダ[AvgBuffer] = Encoders.productの

  オーバーライドDEF outputEncoder:エンコーダ[二] = Encoders.scalaDouble 
}

  

おすすめ

転載: www.cnblogs.com/liangyan131/p/12013615.html