Flink的数据转换Transformation

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大数据” ,共同进步!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值