我正在寻找一种方法将数据从Apache Spark导出到JSON格式的各种其他工具。我认为必须有一种非常简单的方法来做到这一点。
示例:我有以下JSON文件'jfile.json':
{"key":value_a1, "key2":value_b1},
{"key":value_a2, "key2":value_b2},
{...}
其中文件的每一行都是JSON对象。这些文件可以通过
轻松读入PySparkjsonRDD = jsonFile('jfile.json')
然后看起来像(通过调用jsonRDD.collect()):
[Row(key=value_a1, key2=value_b1),Row(key=value_a2, key2=value_b2)]
现在我想将这些类型的文件保存回纯JSON文件。
我在Spark用户列表中找到了这个条目:
http://apache-spark-user-list.1001560.n3.nabble.com/Updating-exising-JSON-files-td12211.html
声称使用
RDD.saveAsTextFile(jsonRDD)
执行此操作后,文本文件看起来像
Row(key=value_a1, key2=value_b1)
Row(key=value_a2, key2=value_b2)
,即jsonRDD刚刚写入文件。在阅读Spark用户列表条目后,我本来期望一种“自动”转换回JSON格式。我的目标是在开头提到一个看起来像'jfile.json'的文件。
我错过了一个非常明显的简单方法吗?
我阅读http://spark.apache.org/docs/latest/programming-guide.html,搜索谷歌,用户列表和堆栈溢出以获得答案,但几乎所有答案都涉及阅读和解析JSON到Spark。我甚至买了“学习星火”这本书,但那里的例子(第71页)只是导致了与上面相同的输出文件。
有人可以帮我吗?我觉得我在这里只缺少一个小链接
提前干杯谢谢!
答案 0 :(得分:5)
您可以使用方法toJson(),它允许您将SchemaRDD转换为JSON文档的MappedRDD。
答案 1 :(得分:1)
我看不出一个简单的方法。一种解决方案是将SchemaRDD
的每个元素转换为String
,最后得到RDD[String]
,其中每个元素都为该行格式化为JSON。因此,您需要编写自己的JSON序列化程序。这很容易。它可能不是超快但它应该并行工作,并且您已经知道如何将RDD
保存到文本文件中。
关键的见解是,您可以通过调用SchemaRDD
方法从schema
中获取模式的表示。然后,地图递送给您的每个Row
需要递归遍历并与架构一起遍历。这实际上是针对平面JSON的串联列表遍历,但您可能还需要考虑嵌套的JSON。
剩下的只是Python的一个小问题,我不会说,但我确实有这个working in Scala,以防它帮助你。 Scala代码密集的部分实际上并不依赖于深入的Spark知识,所以如果你能理解基本的递归并且知道Python,那么你应该能够使它工作。您的大部分工作是弄清楚如何在Python API中使用pyspark.sql.Row
和pyspark.sql.StructType
。
提醒一句:我很确定我的代码在缺少值的情况下还不起作用 - formatItem
方法需要处理null元素。
修改:在 Spark 1.2.0 中,toJSON
方法已引入SchemaRDD
,使其成为很多更简单的问题 - 请参阅@jegordon的答案。
答案 2 :(得分:0)
我一直在SQL控制台中直接在Spark SQL中使用org.apache.spark.sql.json
。不是最有效的方式,它可能被视为黑客,但它完成了工作。
CREATE TABLE jsonTable (
key STRING,
value STRING
)
USING org.apache.spark.sql.json
OPTIONS (
PATH "destination/path"
);
创建表后,从已注册的临时表或任何其他表中插入数据
INSERT OVERWRITE TABLE jsonTable
SELECT * FROM tempTable;
注意:似乎这是启动一个配置单元映射,减少了在提供的路径下创建多个文件部分的作业。预期执行缓慢
注意:创建表时提供的路径位于hdfs,而不是本地文件系统。
注意:我没有尝试使用SQLContext.sql将其嵌入到脚本中,但它可能是可行的
注意:从表中选择jsonTable可能会因序列化而失败