스칼라 애플리케이션 --UDF : 사용자 정의 함수

하둡은 window10에서, IDA와 메이븐 프로젝트를 만들어 설치했습니다.

    <특성> 
        <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를> 
            <version>은 $ {spark.version} </ 버전> 
        </ 의존성> 
        <의존성> 
            < 의 groupId> org.apache.spark </의 groupId> 
            <artifactId를> 스파크 SQL _ scala.version $ {} </ artifactId를> 
            <version>은 $ {스파크.버전} </ 버전> 
        </ 의존성>  
        <의존성>
            <의 groupId> org.apache.spark </의 groupId> 
            <artifactId를> 스파크 스트리밍 _ scala.version $ {} </ artifactId를> 
            <version>은 $ {spark.version} </ 버전> 
        </ 의존성> 
        <의존성> 
            <의 groupId > org.apache.spark </의 groupId> 
            <artifactId를> 스파크 실 _ scala.version $ {} </ artifactId를> 
            <version>은 $ {spark.version} </ 버전> 
        </ 의존성> 

        <의존성> 
            <의 groupId>의 MySQL </의 groupId> 
            <artifactId를> MySQL을 커넥터 자바 </ artifactId를> 
            <version>은 8.0.16 </ 버전> 
        </ 의존성>
    </ 의존성> 


    <빌드>
        <finalName> learnspark </ finalName> 
                <의 groupId> org.apache.maven.plugins </의 groupId>finalName> learnspark </ finalName> 
        <플러그인> 
            <플러그인>
                <의 groupId> net.alchim31.maven </의 groupId> 
                <artifactId를> 스칼라 - 받는다는 - 플러그인 </ artifactId를> 
                <버전> 3.2.2 </ 버전> 
                <실행> 
                    <실행> 
                        <목표> 
                            <목표> 컴파일 </ 목표 > 
                            <목표> testCompile </ 목표> 
                        </ 목표> 
                    </ 실행> 
                </ 실행> 
            </ 플러그인> 
            <플러그인> 
                <버전> 3.0.0 </ 버전> 
                <구성>
                <artifactId를> 받는다는 - 조립 플러그인 </ artifactId를> 
                    <아카이브> 
                        <매니페스트> 
                            <mainClass> 배우 </ mainClass> 
                        </ 매니페스트> 
                    </ 아카이브> 
                    <descriptorRefs> 
                        <descriptorRef> 항아리-와 의존성 </ descriptorRef> 
                    < / descriptorRefs> 
                </ 구성> 
                <실행> 
                    <실행> 
                        <ID> 메이크업 조립체 </ ID> 
                        <위상> 패키지 </ 위상>
                        <목표> 
                            <목표> 하나 </ 목표>
                        </ 목표> 
                    </ 실행>
                </ 실행> 
            </ 플러그인> 
        </ 플러그인> 
    </ 빌드>

  

데이터 준비 :

{ "이름": "张3", "나이": 20} 
{ "이름": "李네", "나이": 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 열, DataFrame, 데이터 집합, 인코더, 인코더, 행, SparkSession, TypedColumn}. 

/ ** 
 *는 UDF : 사용자 정의 함수 
 * / 

오브젝트 {UDF를 

  DEF 주 (인수 : 어레이 [문자열]) : 단위 = { 
    System.setProperty를 ( "hadoop.home.dir", "D : \\ gitworkplace \\ \\ winutils 하둡 2.7.1") 
// 이는 경로 I의 하둡을 지정하는 데 사용 아무런 문제가 당신의 하둡 환경 변수, 당신은 쓸 수 없습니다 
    sparkConf = 새로운 sparkConf (: 발 sparkConf ( "지역 [*]") setAppName ( "UDF")를 setMaster을 ..) 

    SparkSession 만들기 //
    스파크 발 : SparkSession = SparkSession.builder.config (sparkConf) .getOrCreate () 

    가져 오기 spark.implicits._ 

    // json으로 DataFrame에서 읽어 얻은 
    발 프레임 : DataFrame = spark.read.json ( "데이터 / INPUT / 사용자 /user.json ") 

    frame.createOrReplaceTempView ("사용자 ") 

    : // 경우 나는 간단한 기능 검사 사용자 정의 
    addName"(X spark.udf.register ( " 이름 => 문자열)": "+ 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 
  } 

  계산 // 데이터 구조를 
  = {StructType : 재정 DEF bufferSchema 
    . ( "COUNT", LongType를) .add 새로운 새로운 StructType () 추가 ( "SUM", LongType을) 
  } 

  // 데이터 유형은 함수에 의해 리턴 
  재정의 DEF를 dataType와 : 데이터 형식 = DoubleType

  // 함수 안정화 
  true로 = 부울 : 재정 DETERMINISTIC DEF 

  전에 초기화 // 계산 버퍼 영역 
  (: MutableAggregationBuffer 버퍼) 재정 초기화 DEF 단위 = { 
    // 아니 이름 만 구조 
    완충액 (0) = 0L 
    버퍼. (1) = 0L는 
  } 

  질의 결과에 따라,에 대한 캐시의 업데이트 // 
  오버라이드 DEF 업데이트 (완충액 : MutableAggregationBuffer를 INPUT : 행) 단위 = { 
    (0) = buffer.getLong (0) + input.getLong (0) 완충액 
    (완충액 1. .) buffer.getLong = (1) + 1이다. 
  } 

  복수의 노드 // 병합 버퍼 영역 
  무시 DEF 병합 (Buffer1 : MutableAggregationBuffer, Buffer2 : 행) 단위 = {  
    Buffer1 (0) = Buffer1 .getLong (0) + buffer2.getLong (0 )
    . Buffer1 (1) buffer1.getLong = (1) + Buffer2. .getLong. (1) 
  } 

  // 버퍼 계산 것들은 최종 리턴 결과를 수득
  (: 행 버퍼) = {있는 Any는 def는 재정 평가 
    buffer.getLong (0) .toDouble / buffer.getLong (1). 
  } 
} 


/ ** 
 * 기능의 폴리 (강한 타입)의 정의 
 * / 

케이스 클래스이 UserBean (이름 : 문자열, 연령 : 디지털 파일을 기본 //에서 BigInt)는에서 BigInt 읽어 
케이스 클래스 AvgBuffer (var에 SUM을 다음에서 BigInt, VAR 수 : INT) 

클래스 MyAgeAvgClassFunction이 (가) [이 UserBean, AvgBuffer, 더블] {에 어 그리 게이터를 확장 

  // 초기화 버퍼 
  데프 제로 재정의를 : = {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