如何按多个字段对JavaRDD <row>进行排序,只保留Java Spark中的特定数据

时间:2016-07-15 08:30:11

标签: java apache-spark spark-dataframe

我有一个类型为JavaRDD<Row>的输入数据。 Row有两个字段。

[
  {"fieldName":"requestId", "fieldType":"String"}, 
  {"fieldName":"price", "fieldType":"double"}
]

许多requestId中可能会复制priceRows。我的目的是保留Row priceRows requestId 76044601-8029-4e09-9708-41dd125ae4bb 1676.304091136485 76044601-8029-4e09-9708-41dd125ae4bb 3898.9987591932413 ad0acb4a-100d-4624-b863-fcf275ce28db 7518.603722172683 76044601-8029-4e09-9708-41dd125ae4bb 3308.4421575701463 26f639bc-2041-435c-86da-73b997c0cc64 1737.7186292370193 beeb7fc1-2a2d-4943-8237-c281ee7c9617 4941.882928279789 26f639bc-2041-435c-86da-73b997c0cc64 1710.328581775302 相同76044601-8029-4e09-9708-41dd125ae4bb 3898.9987591932413 ad0acb4a-100d-4624-b863-fcf275ce28db 7518.603722172683 26f639bc-2041-435c-86da-73b997c0cc64 1737.7186292370193 beeb7fc1-2a2d-4943-8237-c281ee7c9617 4941.882928279789 。实际上,即使不使用sort,任何方法都可以。

例如,输入如下:

JavaRDD<Row> javaRDD = dataFrame.toJavaRDD().mapToPair(new PairFunction<Row, String, Row>() {
        @Override
        public Tuple2<String, Row> call(Row row) {
            String key = String.valueOf(row.getAs("requestid"));
            return new Tuple2<String, Row>(key, row);
        }
    }).reduceByKey(new Function2<Row, Row, Row>() {
        @Override
        public Row call(Row row1, Row row2) throws Exception {
            double rs1 = Double.parseDouble(String.valueOf(row1.getAs("price")));
            double rs2 = Double.parseDouble(String.valueOf(row2.getAs("price")));
            if (rs1 < rs2) {
                return row2;
            } else {
                return row1;
            }
        }
    }).map(new Function<Tuple2<String, Row>, Row>() {
        @Override
        public Row call(Tuple2<String, Row> tuple) {
            return tuple._2;
        }
    });

输出数据应该是这样的(输出顺序不是问题):

vars:
  example:
    host: whatever
    pass: 123
    port: 577
    domain:
      somevalue: bla.com
      othervalue: foo.com

候选人方法:

example:{{ example | to_nice_yaml | comment(decoration='    ') }}

3 个答案:

答案 0 :(得分:0)

首先,您必须将原始数据创建到JavaRDD对象。

使用mapToPair函数,将数据格式设为键值类型。(键:requestId,value:price)

使用reduceByKey函数,选择最大价格作为键的值。

然后你想要的结果是JavaRDD。

答案 1 :(得分:0)

你应该使用groupByKey,而不是reduceByKey,然后对groupby结果进行排序。

答案 2 :(得分:0)

有一种简单的方法可以实现这一目标。

只需使用groupBy然后使用max,即可获得结果而无需解析为JavaRDD

df.groupBy("requestId").max("price").show();

<强>测试

输入:

{"requestId": "1", "price": 10}
{"requestId": "1", "price": 15}
{"requestId": "1", "price": 19}
{"requestId": "2", "price": 20}
{"requestId": "2", "price": 21}
{"requestId": "2", "price": 26}
{"requestId": "3", "price": 30}
{"requestId": "3", "price": 38}

我有:

+---------+----------+
|requestId|max(price)|
+---------+----------+
|        1|        19|
|        2|        26|
|        3|        38|
+---------+----------+