Flink DataStream之min()与minBy(),max()与maxBy()区别详解

在Flink中有一类滚动聚合的算子(Rolling Aggregation):

sum()、min()、minBy()、max()、maxBy()

其中,对于min()和minBy(),max()和maxBy()之间的区别,具体如下:

1、处理的数据只有两个字段:

即:只有分组字段和比较字段,

如城市温度数据(city,temp),其中city用来分组(keyBy),temp用来比较(min/minBy),

那么,此时min()和minBy()的作用是一样的,都是得到比较字段的最小值。案例代码如下:读者也可以自己写个demo测试一下。

public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        conf.setString("rest.port","8091");
        StreamExecutionEnvironment env = StreamExecutionEnvironment.createLocalEnvironmentWithWebUI(conf);
        //从端口号获取数据
        DataStreamSource<String> dataSource = env.socketTextStream("10.12.36.102", 8888);

        //=========================两个字段==============
        //将数据转化为Tuple2类型,(city,temp)
        SingleOutputStreamOperator<Tuple2<String, Float>> mapedStream = dataSource.map(new MapFunction<String, Tuple2<String, Float>>() {
            @Override
            public Tuple2<String, Float> map(String value) throws Exception {
                String[] fields = value.split(" ");
                return Tuple2.of(fields[0], Float.valueOf(fields[1]));
            }
        });
        
        //按照city进行分组
        KeyedStream<Tuple2<String, Float>, String> keyedStream = mapedStream.keyBy(tp -> tp.f0);
        
        //按照temp进行比较
        //测试min算子
        SingleOutputStreamOperator<Tuple2<String, Float>> minStream = keyedStream.min(1);

        //测试minBy算子
        //SingleOutputStreamOperator<Tuple2<String, Float>> minByStream = keyedStream.minBy(1);
      
        minStream.print();
        env.execute();
    }

2、处理数据有多个字段:

即:除分组字段、比较字段外,还有一些其他的字段,如Tuple3及以上类型,或者POJO类型数据

2.1 对于min()算子

返回的是分组字段和比较字段的最小值,除分组字段和比较字段之外的字段,则返回的是第一次出现时的值,也就是说min()返回指定字段的最小值,但却不是该最小值所在的那一整条数据。

(干说文字可晦涩,我们举个例子说明一下)

以 (prov,city,temp)类型数据为例,其中prov进行分组,temp进行比较,temp不参与任何情况。

输入:(辽宁,大连,36.5)-->输出(辽宁,大连,36.5),因为此时只有这一条记录

输入:(辽宁,沈阳,32.4)-->输出(辽宁,大连,32.4),此时最小值为32.4,但是city字段显示的是第一次出现的值

输入:(辽宁,锦州,10.0)-->输出(辽宁,大连,10.0),此时最小值为10.0,city字段仍然显示的是第一个出现的值

2.2 对于minBy()算子

返回的就是最小值所在的最新的整条数据。

(辽宁,大连,36.5)-->输出(辽宁,大连,36.5)

(辽宁,沈阳,32.4)-->输出(辽宁,沈阳,32.4)

(辽宁,锦州,10.0)-->输出(辽宁,锦州,10.0)

★★★★★★对于minBy()算子,还有一个boolean参数★★★★★★

minBy(2),默认缺省值就为true,当比较字段最小值出现相等的情况时,其他字段返回第一次出现时的值,举例如下:

(辽宁,大连,32)-->输出(辽宁,大连,32)

(辽宁,沈阳,32)-->输出(辽宁,大连,32),city返回的是第一次出现的值

(辽宁,锦州,32)-->输出(辽宁,大连,32),city仍返回的是第一次出现的值

minBy(2,fasle),设置为false时,当比较字段最小值出现相等的情况时,则返回最新的最小值所在的整条数据

(辽宁,大连,32)-->输出(辽宁,大连,32)

(辽宁,沈阳,32)-->输出(辽宁,沈阳,32),返回最新的整条数据

(辽宁,锦州,32)-->输出(辽宁,锦州,32),返回最新的整条数据

处理多字段数据的案例代码如下,读者们可以自测一下:

public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        conf.setString("rest.port","8091");
        StreamExecutionEnvironment env = StreamExecutionEnvironment.createLocalEnvironmentWithWebUI(conf);

        DataStreamSource<String> dataSource = env.socketTextStream("10.12.36.102", 8888);

        //==============三个字段=====================
        //将数据转化为Tuple3类型
        SingleOutputStreamOperator<Tuple3<String,String, Float>> mapStream = dataSource.map(new MapFunction<String, Tuple3<String,String, Float>>() {
            @Override
            public Tuple3<String,String, Float> map(String value) throws Exception {
                String[] fields = value.split(" ");
                return Tuple3.of(fields[0], fields[1],Float.valueOf(fields[2]));
            }
        });
        
        //按照prov分组
        KeyedStream<Tuple3<String,String, Float>, String> keyStream = mapStream.keyBy(tp->tp.f0);

        //按temp进行比较
        SingleOutputStreamOperator<Tuple3<String,String, Float>> minStream = keyStream.minBy(2,false);

        minStream.print();
        env.execute();
    }

好啦,这样举个例子应该就清晰多了,最后再总结一下:

1、处理数据只有两个字段:

        min()和minBy()作用一样,均为取最小值

2、处理数据有多个字段:

        ★min()返回比较字段的最小值,但不是最小值所在的整体数据

        ★minBy()返回比较字段所在的最新整体数据

                如果比较字段出现最小值相等的情况:

                > 使用minBy(...,true)时,(true为默认可省略),其他字段返回第一次出现时的值

                > 使用minBy(...,false)时,返回最新的最小值所在的整条数据


我是smallk,自学大数据,拿到百度、京东、小米、顺丰、58、哈罗、海康等22家大数据offer,欢迎仍在数据路上的小伙伴,我们一起讨论前行。


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值