datastream转换操作
single-datastream操作:定义对单个datastream数据集元素的处理逻辑map、flatmap、filter、keyby、reduce、aggregation。
multi-datastream操作:定义对多个datastream数据集元素的处理逻辑union、connect、comap、coflatmap、split、select、iterate。
datastream
map()
调用用户定义的MapFunction对DataStream[T]数据进行处理,形成新的Data-Stream[T],其中数据格式可能会发生变化,常用作对数据集内数据的清洗和转换。例如将输入数据集中的每个数值全部加1处理,并且将数据输出到下游数据集,同时,也 支持自定义实现MapFunction接口,编写自己的逻辑,做一些复杂的操作。
map()基本是一对一服务,即输入一个元素输出一个元素。
flatMap()
对于map()来说,实现MapFunction也只是支持一对一的转换。那么有时候你需要处理一个输入元素,但是要输出一个或者多个输出元素的时候,就可以用到flatMap()。使用接口中提供的 Collector ,flatmap() 可以输出你想要的任意数量的元素,也可以一个都不发。
filter
DataStream->DataStream 根据条件进行判断,用于满足条件的数据进行输出,不满足就过滤掉。
keyBy
先看定义,通过keyBy,DataStream→KeyedStream。逻辑上将流分区为不相交的分区。具有相同Keys的所有记录都分配给同一分区。在内部,keyBy()是使用散列分区实现的。指定键有不同的方法。此转换返回KeyedStream,其中包括使用被Keys化状态所需的KeyedStream。
keyby类似于sql中的group by,将数据进行了分组。后面基于keyedSteam的操作,都是组内操作。
aggregation
常见的聚合操作有sum、max、min等,这些聚合操作统称为aggregation。aggregation需要一个参数来指定按照哪个字段进行聚合。跟keyBy相似,我们可以使用数字位置来指定对哪个字段进行聚合,也可以使用字段名。
与批处理不同,这些聚合函数是对流数据进行数据,流数据是依次进入Flink的,聚合操作是对之前流入的数据进行统计聚合。sum算子的功能对该字段进行加和,并将结果保存在该字段上。min操作无法确定其他字段的数值。
aggregation聚合算子常用有sum、min、max 这些算子需要指定按照哪个字段(一个参数)进行聚合,下面我们以min、minBy为例讲解说明
private static void aggregation3() throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
ArrayList<Student> studentList = new ArrayList<>();
Student student = new Student();
student.setAge(7);
student.setName("a1");
student.setProperty("1");
studentList.add(student);
Student student2 = new Student();
student2.setAge(8);
student2.setName("a2");
student2.setProperty("2");
studentList.add(student2);
Student student3 = new Student();
student3.setAge(9);//19
student3.setName("a3");
student3.setProperty("3");
studentList.add(student3);
Student student4 = new Student();
student4.setAge(11);
student4.setName("a3");
student4.setProperty("4");
studentList.add(student4);
DataStreamSource<Student> source = env.fromCollection(studentList);
SingleOutputStreamOperator<Student> aggStream = source.keyBy(new KeySelector<Student, String>() {
@Override
public String getKey(Student student) throws Exception {
return student.getName();
}
}).min("age");
aggStream.print("aggStream");
env.execute("aggStream");
}
-
min执行结果如下:
aggStream:3> name=a2 age= 8 property=2
aggStream:3> name=a3 age= 9 property=3
aggStream:3> name=a3 age= 9 property=3
aggStream:2> name=a1 age= 7 property=1
student3.setAge(19);//此处改为19我们在执行结果如下:
aggStream:3> name=a2 age= 8 property=2
aggStream:3> name=a3 age= 19 property=3
aggStream:3> name=a3 age= 11 property=3
aggStream:2> name=a1 age= 7 property=1
我们可以看到如果先找到最小值,那最小值会被保存,但第二次property值不正确。
-
下面我们改为minBy再次执行:
student3.setAge(9); .minBy("age");
aggStream:3> name=a2 age= 8 property=2
aggStream:3> name=a3 age= 9 property=3
aggStream:3> name=a3 age= 9 property=3
aggStream:2> name=a1 age= 7 property=1
再次修改执行:
student3.setAge(19);
.minBy("age");
aggStream:3> name=a2 age= 8 property=2
aggStream:3> name=a3 age= 19 property=3
aggStream:3> name=a3 age= 11 property=4
aggStream:2> name=a1 age= 7 property=1
我们看到minBy无论是第一次执行,还是第二次执行property针对最小值来说都是正确的。
如果觉得文章能帮到您,欢迎关注微信公众号:“蓝天Java大数据” ,共同进步!