4、Flink里的UDF函数

一、函数类(Function Classes)

Flink暴露了所有udf函数的接口(实现方式为接口或者抽象类)。例如使用Map要实现MapFunction,使用Filter要实现FilterFunction,使用Process要实现ProcessFunction等等。
以Filter为例:

	//方式一,自定义外部类实现FilterFunction
    DataStream<String> filterResult = stringDataStream.filter(new MyFilter());
	public static class MyFilter implements FilterFunction<String>{
	
	    @Override
	    public boolean filter(String s) throws Exception {
	        return s.contains("flink");
	    }
    }


	//方式二,定义成匿名内部类
    DataStream<String> filterResult = stringDataStream.filter(new FilterFunction<String>() {
        @Override
        public boolean filter(String s) throws Exception {
            return s.contains("flink");
        }
    });


    //方式三,定义成lambada表达式
    DataStream<String> filterResult = stringDataStream.filter(data->data.contains("flink"));

上面三种方式都可以实现FilterFunction,但是只能进行固定的判断,如果想传入参数到类中,需要用以下的方式:

    //实现接口并传递参数
    DataStream<String> filterResult = stringDataStream.filter(new MyFilter("flink"));

	public static class MyFilter implements FilterFunction<String>{

        private String keyword;

        MyFilter(String keyword){
            this.keyword=keyword;
        }

        @Override
        public boolean filter(String s) throws Exception {
            return s.contains(this.keyword);
        }
    }

二、富函数(Rich Functions)

“富函数”是DataStream API提供的一个函数类的接口,所有Flink函数类都有其Rich版本。它与常规函数的不同在于,可以获取运行环境的上下文,并拥有一些生命周期方法,所以可以实现更复杂的功能。
例如:
1)RichMapFunction
2)RichFlatMapFunction
3)RichFilterFunction

Rich Function有一个生命周期的概念。典型的生命周期方法有:
open()方法是rich function的初始化方法,当一个算子例如map或者filter被调用之前opne()会被调用,可以做初始化工作。
close()方法是生命周期中最后一个调用的方法,做一些清理工作。
getRuntimeContext()方法提供了函数的RuntimeContext的一些信息,例如函数执行的并行度,任务的名字,以及state状态。
之前使用那些算子实现的只是最基础的函数,并没有实现富函数,所以上面三个方法都没办法使用。
以Map方法为例:

    DataStream<Tuple2<Integer, String>> result = mapResult.map(new RichMapFunction<SensorReading, Tuple2<Integer, String>>() {
        @Override
        public Tuple2<Integer, String> map(SensorReading sensorReading) throws Exception {
            return new Tuple2<>(getRuntimeContext().getIndexOfThisSubtask(), sensorReading.getId());
        }

        @Override
        public void open(Configuration parameters) throws Exception {
            System.out.println("my map open!!!");
        }

        @Override
        public void close() throws Exception {
            System.out.println("my map close!!!");
        }
    });

    result.print();
    env.execute();

执行结果:
在这里插入图片描述
设置了并行度为几,就有几个分区,每个分区都有一个类的实例。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flink 中使用 Json 解析 UDF 函数,需要使用 Flink 自带的 Json 库,即 `flink-json`。具体步骤如下: 1. 添加依赖 在 `pom.xml` 中添加以下依赖: ```xml <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-json</artifactId> <version>${flink.version}</version> </dependency> ``` 其中,`${flink.version}` 是 Flink 的版本号,需要根据实际情况修改。 2. 编写 UDF 函数Flink 中,UDF 函数需要实现 `org.apache.flink.table.functions.ScalarFunction` 接口。具体实现过程如下: ```java import org.apache.flink.api.common.typeinfo.TypeInformation; import org.apache.flink.api.java.typeutils.TypeExtractor; import org.apache.flink.table.functions.ScalarFunction; import org.apache.flink.types.Row; import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.ObjectMapper; import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.JsonNode; public class JsonParse extends ScalarFunction { public Row eval(String jsonStr, String key) { ObjectMapper mapper = new ObjectMapper(); try { JsonNode jsonNode = mapper.readTree(jsonStr); JsonNode valueNode = jsonNode.get(key); if (valueNode == null) { return null; } TypeInformation<?>[] fieldTypes = new TypeInformation<?>[1]; fieldTypes[0] = TypeExtractor.getForClass(String.class); Row row = new Row(1); row.setField(0, valueNode.asText()); return row; } catch (Exception e) { return null; } } } ``` 该 UDF 函数的作用是从 Json 字符串中解析出指定的 key 对应的值,返回一个包含该值的 Row 对象。 3. 使用 UDF 函数Flink SQL 中,可以使用 `json_parse` 函数来调用 `JsonParse` UDF 函数。示例代码如下: ```sql SELECT json_parse('{"name":"Alice","age":20}', 'name') as name FROM table_name; ``` 该语句将返回一个包含字符串 `"Alice"` 的 Row 对象。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值