104.Spark大型电商项目-各区域热门商品统计-开发自定义UDAF聚合函数之group_concat_distinct()

目录

代码

ConcatLongStringUDF.java

GroupConcatDistinctUDAF.java

AreaTop3ProductSpark.java


本篇文章记录各区域热门商品统计-开发自定义UDAF聚合函数之group_concat_distinct()。

代码

spark.product

ConcatLongStringUDF.java

package graduation.java.spark.product;

import org.apache.spark.sql.api.java.UDF3;

/**
 * FileName: ConcatLongStringUDF
 * Author:   hadoop
 * Email:    3165845957@qq.com
 * Date:     19-4-1 下午8:27
 * Description:
 * 将两个字段拼接起来(使用指定的分隔符)
 */
public class ConcatLongStringUDF implements UDF3<Long,String,String,String> {
    private static final  long serialVersionUID = 1L;
    @Override
    public String call(Long v1, String v2, String split) throws Exception {
        return String.valueOf(v1) + split+v2;
    }
}

GroupConcatDistinctUDAF.java

package graduation.java.spark.product;

import org.apache.spark.sql.Row;
import org.apache.spark.sql.expressions.MutableAggregationBuffer;
import org.apache.spark.sql.expressions.UserDefinedAggregateFunction;
import org.apache.spark.sql.types.DataType;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.StructType;

import java.util.Arrays;

/**
 * FileName: GroupConcatDistinctUDAF
 * Author:   hadoop
 * Email:    3165845957@qq.com
 * Date:     19-4-1 下午8:39
 * Description:
 * 内部拼接去重函数(group_concat_distinct)
 */
public class GroupConcatDistinctUDAF  extends UserDefinedAggregateFunction {

    //指定输入数据字段和类型
    private StructType inputScheam = DataTypes.createStructType(Arrays.asList(DataTypes.createStructField("cityInfo",DataTypes.StringType,true)));
    //指定缓冲数据的字段和类型
    private StructType bufferSchema = DataTypes.createStructType(Arrays.asList(DataTypes.createStructField("bufferCityInfo",DataTypes.StringType,true)));
    //指定返回类型
    private DataType dataType = DataTypes.StringType;

    //指定是否是确定性
    private boolean deterministic = true;

    @Override
    public StructType inputSchema() {
        return inputScheam;
    }

    @Override
    public StructType bufferSchema() {
        return bufferSchema;
    }

    @Override
    public DataType dataType() {
        return dataType;
    }

    @Override
    public boolean deterministic() {
        return deterministic;
    }

    /**
     * 初始化,可以认为是在内部指定一个初始值
     * @param buffer
     */
    @Override
    public void initialize(MutableAggregationBuffer buffer) {
        buffer.update(0,"");
    }

    /**
     * 更新
     * 可以认为 一个一个的将组内的字段传递进来进行逻辑拼接
     * @param buffer
     * @param input
     */
    @Override
    public void update(MutableAggregationBuffer buffer, Row input) {
        // 缓冲中的是已经拼接的城市信息
        String bufferCityInfo = buffer.getString(0);

        //传递进来的城市信息
        String cityInfo = input.getString(0);
        //实现逻辑拼接
        //判断:之前没有拼接过的某个城市信息,那么这里才可以把它拼接进去
        if (!bufferCityInfo.contains(cityInfo)){
            if ("".equals(bufferCityInfo)){
                bufferCityInfo += cityInfo;
            }else {
                bufferCityInfo += "," + cityInfo;
            }
            buffer.update(0,bufferCityInfo);
        }
    }

    /**
     * 合并
     * update操作,可能是针对一个分组内的部分数据,在某个节点上发生的
     * 但是可能一个分组内的数据,会分布在多个节点上处理
     * 此时就要用merge操作,将各个节点上分布式拼接好的串,合并起来
     */

    @Override
    public void merge(MutableAggregationBuffer buffer1, Row buffer2) {
        String bufferCityInfo1 = buffer1.getString(0);
        String bufferCityInfo2 = buffer2.getString(0);
        for (String cityInfo : bufferCityInfo2.split(",")){
            if (! bufferCityInfo1.contains(cityInfo)){
                if ("".equals(bufferCityInfo1)){
                    bufferCityInfo1 += cityInfo;
                }else {
                    bufferCityInfo1 += ","+ cityInfo;
                }
            }
        }
        buffer1.update(0,bufferCityInfo1);

    }

    @Override
    public Object evaluate(Row row) {
        return row.getString(0);
    }
}

AreaTop3ProductSpark.java

        //3.注册字符串拼接函数
        sqlContext.udf().register("concat_long_string",new ConcatLongStringUDF(),DataTypes.StringType);
        sqlContext.udf().register("group_concat_distinct",new GroupConcatDistinctUDAF());

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值