我使用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>>
。
答案 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
如果有人有更好的方法来获得相同的结果,请告诉我。