使用Java

时间:2016-01-30 00:50:38

标签: java json apache-spark parquet

我使用Spark 1.5.2和Java,我试图读取包含源自JSON文件的数据的镶木地板文件。我很难弄清楚如何在最初包含嵌套JSON的字段中读取,但现在是WrappedArray<WrappedArray<String>>。我已经查看了Spark页面中的Parquet文件,但是没有一个例子符合我的要求。我做了一些搜索,发现了一些非常接近但却特异于scala的东西。

以下是原始JSON的示例:

{"page_number":1,"id_groups":[{"ids":["60537"]},{"ids":["65766","7368815"]}]}

我遇到问题的字段是id_groups字段。我读了镶木地板文件,并做了一个节目。架构如下所示:

StructField(id_groups,ArrayType(StructType(StructField(ids,ArrayType(StringType,true),true)),true),true))

我猜我需要为该字段创建架构,但我无法使用Spark Java API来弄清楚如何做到这一点。

这篇文章似乎很有希望(显示scala代码为嵌套数据创建模式),但我不知道如何使用Java复制类似的东西。

spark-specifying-schema-for-nested-json

有关如何从镶木地板文件中读取id_groups数据的任何建议吗?

IntelliJ在逐步执行代码时显示id_groups字段为WrappedArray<WrappedArray<String>>

1 个答案:

答案 0 :(得分:0)

我找到了一种方法来读取源自嵌套JSON的数据,但我并不特别喜欢我这样做的方式。

DataFrame parquetData = sqlContext.read().parquet("/Users/leewallen/dev/spark_data/out/ParquetData");
parquetData.registerTempTable("pd");
DataFrame idGroupsDataFrame = sqlContext.sql("select id_groups.ids from pd");

List<String> idList = idGroupsDataFrame.javaRDD()
                                       .map((Function<Row, String>) row -> {
    List<String> ids = new ArrayList<>();
    List<WrappedArray<String>> wrappedArrayList = row.getList(0);
    java.util.Iterator<WrappedArray<String>> wrappedArrayIterator = wrappedArrayList.iterator();
    while (wrappedArrayIterator.hasNext()) {
        WrappedArray<String> idWrappedArray = wrappedArrayIterator.next();
        Iterator<String> stringIter = idWrappedArray.iterator();
        List<String> tempIds = new ArrayList<>();
        while (stringIter.hasNext()) {
            tempIds.add(stringIter.next());
        }

        ids.add(tempIds.stream()
                       .reduce((s1, s2) -> String.format("%s,%s", s1, s2))
                       .get());
    }

    return ids.stream()
              .reduce((s1, s2) -> String.format("%s|%s", s1, s2))
              .get();
}).collect();

idList.forEach(id -> System.out.println(id));

如果输入数据如下所示:

{"page_number":1,"id_groups":[{"ids":["60537"]},{"ids":["65766","7368815"]}]}

然后打印输出如下:

60537|65766,7368815

如果有人有更好的方法来获得相同的结果,请告诉我。