Flink 自定义函数生成K V键值对的JSON串

需求:将表中的两字段使用SQL存入新表中的一个字段,存储格式是KV键值对。使用自定义函数实现
import java.util.HashMap;
import java.util.Map;

/**
 * @author liuhongbo
 * @date 2023-02-10 15:00
 */
public class CollectSegmentAttrAcc implements java.io.Serializable {

    private static final long serialVersionUID = 1521279572627987607L;

    private Map<String, String> content = new HashMap<>();

    public Map<String, String> getContent() {
        return content;
    }

    public void setContent(Map<String, String> content) {
        this.content = content;
    }
}
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.flink.table.functions.AggregateFunction;

/**
 * @author liuhongbo
 * @date 2023-02-10 15:00
 */
public class CollectSegmentAttrs extends AggregateFunction<String, CollectSegmentAttrAcc> {

    @Override
    public String getValue(CollectSegmentAttrAcc accumulator) {
        String result = StringUtils.EMPTY;
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            Map<String, String> content = accumulator.getContent();
            if (MapUtils.isNotEmpty(content)) {
                result = objectMapper.writeValueAsString(content);
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    @Override
    public CollectSegmentAttrAcc createAccumulator() {
        return new CollectSegmentAttrAcc();
    }

    public void accumulate(CollectSegmentAttrAcc accumulator, String attrCode,String attrValue) {
        Map<String, String> content = accumulator.getContent();
        if (StringUtils.isNoneBlank(attrCode, attrValue)) {
            content.put(attrCode, attrValue);
        }
    }

    public void retract(CollectSegmentAttrAcc accumulator, String attrCode,String attrValue) {
        accumulator.getContent().remove(attrCode);
    }

    public void merge(CollectSegmentAttrAcc acc, Iterable<CollectSegmentAttrAcc> it) {
        Iterator<CollectSegmentAttrAcc> iter = it.iterator();
        while (iter.hasNext()) {
            CollectSegmentAttrAcc next = iter.next();
            Map<String, String> content = next.getContent();
            content.forEach((k, v) -> {
                acc.getContent().put(k, v);
            });
        }
    }

    public void resetAccumulator(CollectSegmentAttrAcc acc) {
        acc.getContent().clear();
    }
}

将函数打包成jar,上传至服务器指定目录。
在SQL中的应用是,先引用jar,再创建自定义函数。

ADD JAR '/devops/flink/script/flink-quickstart-1.0-SNAPSHOT.jar';
CREATE TEMPORARY FUNCTION CollectSegmentAttrs AS 'com.airoc.flink.udf.CollectSegmentAttrs';

在SQL中的使用如下:

LEFT JOIN (SELECT SEGMENT_ID,CollectSegmentAttrs(ATTR_CODE, ATTR_VALUE) AS SEGMENT_ATTRS FROM table_name group by SEGMENT_ID )
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flink 中的自定义函数是实现自己的业务逻辑的一种方式。常用的自定义函数包括 MapFunction、FlatMapFunction、FilterFunction、ReduceFunction 等。下面以 MapFunction 为例,介绍如何自定义函数。 假设我们有一个输入数据集合,数据格式为 (String, Int),表示一个字符和一个整数。现在我们想要对这个数据集合进行处理,将字符中所有的小写字母转换成大写字母,并将整数加上 1。可以通过自定义 MapFunction 来实现: ```java public class MyMapFunction implements MapFunction<Tuple2<String, Integer>, Tuple2<String, Integer>> { @Override public Tuple2<String, Integer> map(Tuple2<String, Integer> value) throws Exception { String str = value.f0.toUpperCase(); int num = value.f1 + 1; return new Tuple2<>(str, num); } } ``` 上面的代码中,MyMapFunction 实现了 MapFunction 接口,并重写了 map 方法。在 map 方法中,我们将输入的 Tuple2 中的字符转换成大写字母,并将整数加上 1,最后返回一个新的 Tuple2 对象。 使用自定义函数时,可以通过以下方式进行调用: ```java DataStream<Tuple2<String, Integer>> result = input.map(new MyMapFunction()); ``` 其中,input 表示输入的数据流,MyMapFunction 表示自定义的函数。 在 Flink 中,除了上述提到的 MapFunction、FlatMapFunction、FilterFunction、ReduceFunction 等常用函数之外,还可以自定义 WindowFunction、KeySelector、ProcessFunction、SinkFunction 等函数。这些函数的使用方式与上述介绍的方式类似,只需要实现对应的接口并重写对应的方法即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值