Presto如何开发自定义聚合函数

(一)先了解一下什么是自定义聚合函数

  1. 其实就是根据你自己的业务去进行定义你自己想要实现的方法,比如说Mysql中的sum() 方法,就是求某个字段的累加之和,那么你就可以自己实现自己的 比如说 add() 自定义聚合函数方法

(二)如何开发自定义聚合函数

  1. 首先需要实现Presto提供的Plugin接口,然后把要实现的聚合函数所在的类添加到集合中
package com.tapdb.analytics.presto.udaf;

import com.google.common.collect.ImmutableSet;
import io.prestosql.spi.Plugin;

import java.util.Set;

public class TapdbAnalyticsPlugin implements Plugin {

    @Override
    public Set<Class<?>> getFunctions() {
        return ImmutableSet.<Class<?>>builder()
                .add(DateHistogramAggregation.class)
                .add(ArraySumAggregation.class)
                .add(ArrayConstructScalar.class)
                .add(RetentionAggregation.class)
                .add(DecodeBitSetAggregation.class)
                .build();
    }
}
  1. 然后把你想要处理的字段根据其类型传入input()方法的参数中进行处理,这里需要注意如何把你处理好的结果集传给下一个combine()方法,需要通过SliceState进行作为桥梁,当然这个也可以自己进行自定义,output()方法是把最后的结果集进行构造然后,通过Presto提供的API进行构建返回结果。
package com.tapdb.analytics.presto.udaf;

import io.airlift.slice.Slice;
import io.airlift.slice.Slices;
import io.prestosql.spi.block.BlockBuilder;
import io.prestosql.spi.function.*;
import io.prestosql.spi.type.StandardTypes;

/**
 * @Description DecodeBitSetAggregation
 * @Date 2020/6/16
 * @Author wangwei
 */
@AggregationFunction("tapdb_bitset_decode")
public class DecodeBitSetAggregation {

    @InputFunction
    public static void input(@AggregationState SliceState state,
                             @SqlType(StandardTypes.BIGINT) long mask,
                             @SqlType(StandardTypes.BIGINT) long value) {
        if (state.getSlice() == null) {
            long capacity = 30 * Long.BYTES;
            Slice slice = Slices.allocate((int) capacity);
            state.setSlice(slice);
        }
        Slice slice = state.getSlice();
        long retainValue = mask <= 0 ? value ^ mask : value & mask;
        int tmpIndex = 0;
        for (int i = 29; i >= 0; i--) {
            int offset = Long.BYTES * tmpIndex;
            slice.setLong(offset, Long.lowestOneBit(retainValue) == 1 ? 1L : 0L);
            retainValue = retainValue >> 1;
            tmpIndex++;
        }
    }


    @CombineFunction
    public static void combine(@AggregationState SliceState state, @AggregationState SliceState otherState) {
        Slice otherSlice = otherState.getSlice();
        Slice slice = state.getSlice();

        if (otherSlice == null) {
            return;
        }
        if (slice == null) {
            state.setSlice(otherSlice);
            return;
        }

        int indexNum = slice.length() / Long.BYTES;
        for (int i = 0; i < indexNum; ++i) {
            int offset = i * Long.BYTES;
            slice.setLong(offset, slice.getLong(offset) + otherSlice.getLong(offset) > 0 ? 1L : 0L);
        }
    }


    @OutputFunction("array(bigint)")
    public static void output(@AggregationState SliceState state, BlockBuilder out) {
        Slice slice = state.getSlice();
        if (slice == null) {
            out.appendNull();
            return;
        }

        int byteArrayNum = slice.length() / Long.BYTES;
        BlockBuilder blockBuilder = out.beginBlockEntry();

        for (int i = 0; i < byteArrayNum; ++i) {
            int offset = i * Long.BYTES;
            long value = slice.getLong(offset);
            blockBuilder.writeLong(value).closeEntry();
        }
        out.closeEntry();
    }

}

  1. 就是把这个项目打包成一个jar包,然后放到Presto集群所有机器下面的plugin目录下(这里需要自己随便创建一个目录,然后放到自己创建的目录下),然后就是重启集群,使用show functions 查看一下自己定义的聚合函数是不是注册成功,如果成功如图这种。
    在这里插入图片描述
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值