一次为多个过滤器生成模式

时间:2015-10-05 14:55:59

标签: java apache-spark apache-spark-sql

问题 我有趣的是火花1.5.0。我有一个名为events的不同json字符串对象的RDD。每个json对象都有一个字段type。我想为type字段的每个值创建一个不同的数据框。然后我想为每个数据帧生成模式(df.printSchema())。

SAMPLE INPUT

{"a": 1, "b": 2, "type": "x"}
{"a": 1, "c": 2, "type": "x"}
{"c": 1, "d": 2, "type": "y"}
{"d": 1, "e": 2, "type": "y"}

所以我的架构应该类似于:

for type "x":
root
 |-- a: string (nullable = true)
 |-- b: string (nullable = true)
 |-- c: string (nullable = true)

for type "y":
 root
 |-- c: string (nullable = true)
 |-- d: string (nullable = true)
 |-- e: string (nullable = true)

我尝试了什么:

final String[] event_types = {"x", "y"};

for (final String event_type: event_types) {
    JavaRDD<String> filtered_events = events.filter(
        new Function<String, Boolean>() {
            public Boolean call(String s) {
                String event_type_t = null;
                try {
                    JSONObject json_data = new JSONObject(s);
                    event_type_t = json_data.getString("type").toString();
                }
                catch (JSONException e) {
                    return false;
                }
                if (event_type.equalsIgnoreCase(event_type_t)) {
                    return true;
                }
                else {
                    return false;
                }
            }
        }
    );

    DataFrame df = sqlContext.read().option("header", "true").json(filtered_events);
    System.out.println(event_type);
    df.printSchema();

}

有解决方案的问题 它为每个过滤器运行多次传递。如果有多种事件类型,则需要花费大量时间来处理。我想一次性完成。

1 个答案:

答案 0 :(得分:2)

我的猜测是最昂贵的部分实际上是JSON解析。将它推到过滤逻辑之外是有意义的。使用Scala:

val events: RDD[String] = ???
val event_types = List("x", "y")
val df: DataFrame  = sqlContext.read.json(events)

val dfs = event_types.map(t => (t -> df.where($"type" <=> t))).toMap