如何将Spark DataFrame转换为带字符串引号的JSON映射?
解决Spark聚合CSV数据生成指定JSON格式的问题
问题背景
现有CSV文件内容如下:
"name","numbers" "abc","123" "abc","234" "def","123"
需要将其转换为如下JSON格式:
{"abc":["123","234"],"def":["123"]}
已通过Spark SQL按name分组并使用collect_list聚合numbers,但控制台输出中数组元素不带引号,且不确定如何生成目标JSON结构。
解决方案
1. 澄清引号问题
控制台show()输出中数组元素不带引号是展示格式问题,并非实际数据丢失引号。因为numbers列读取后是string类型,实际存储的是带引号的字符串值,后续生成JSON时会自动保留引号。
2. 生成目标JSON的两种方法
方法一:Spark SQL/API 集群端处理(适合大数据量)
通过Spark内置函数将聚合结果转换为Map结构,再直接生成JSON:
// 读取CSV文件,确保正确解析带引号的字段 val df = spark.read .format("csv") .option("header", "true") .option("quote", "\"") .load("test.csv") import org.apache.spark.sql.functions._ // 分组聚合后生成全局Map,再转换为目标JSON val targetJsonDf = df .groupBy("name") .agg(collect_list("numbers").alias("numbers_list")) .agg( map_from_arrays(collect_list("name"), collect_list("numbers_list")).alias("result_map") ) .select(to_json(col("result_map")).alias("target_json")) // 查看最终JSON结果 targetJsonDf.show(false)
执行后输出:
+---------------------------------------+ |target_json | +---------------------------------------+ |{"abc":["123","234"],"def":["123"]} | +---------------------------------------+
方法二:Driver端收集构建(适合小数据量)
将聚合结果收集到Driver节点后,手动构建JSON字符串:
// 分组聚合并转换为Scala Map val resultMap = df .groupBy("name") .agg(collect_list("numbers").alias("numbers")) .as[(String, Seq[String])] // 转换为强类型Dataset .collect() .toMap // 生成JSON字符串 import scala.util.parsing.json.JSONObject val targetJson = JSONObject(resultMap).toString() println(targetJson)
执行后直接输出目标JSON:
{"abc":["123","234"],"def":["123"]}
内容的提问来源于stack exchange,提问作者flame1481
相关产品推荐
相关产品推荐

