spark sql 解析嵌套对象数组的json

发布于 2022-09-07 16:50:40 字数 2562 浏览 28 评论 0

1.现在有json数据如下

{"id":11,"data":[{"package":"com.browser1","activetime":60000},{"package":"com.browser6","activetime":1205000},{"package":"com.browser7","activetime":1205000}]}

{"id":12,"data":[{"package":"com.browser1","activetime":60000},{"package":"com.browser6","activetime":1205000}]}
......
,json里是app的激活时间,目的是分析每个app的总激活时间
我使用sparK sql解析 json

    val sqlContext = sc.sqlContext

    val behavior = sqlContext.read.json("behavior-json.log")
    behavior.cache()

    behavior.createOrReplaceTempView("behavior")
 

    val appActiveTime = sqlContext.sql("SELECT data FROM behavior")    //    sql查询
    
    appActiveTime.show(100,100)  //  打印dataFrame
    appActiveTime.rdd.foreach(println)  //  打印rdd

但是打印出来的dataFrame是这样的

+----------------------------------------------------------------------+
|                                                                  data|
+----------------------------------------------------------------------+
|                        [[60000,com.browser1], [12870000,com.browser]]|
|                          [[60000,com.browser1], [120000,com.browser]]|
|                          [[60000,com.browser1], [120000,com.browser]]|
|                         [[60000,com.browser1], [1207000,com.browser]]|
|                                                [[120000,com.browser]]|
|                        [[60000,com.browser1], [1204000,com.browser5]]|
|                        [[60000,com.browser1], [12075000,com.browser]]|
|                          [[60000,com.browser1], [120000,com.browser]]|
|                         [[60000,com.browser1], [1204000,com.browser]]|
|                          [[60000,com.browser1], [120000,com.browser]]|
|                         [[60000,com.browser1], [1201000,com.browser]]|
|                                              [[1200400,com.browser5]]|
|                         [[60000,com.browser1], [1200400,com.browser]]|
|[[60000,com.browser1], [1205000,com.browser6], [1205000,com.browser7]]|

rdd是这样的

[WrappedArray([60000,com.browser1], [60000,com.browser1])]
[WrappedArray([120000,com.browser])]
[WrappedArray([60000,com.browser1], [1204000,com.browser5])]
[WrappedArray([12075000,com.browser], [12075000,com.browser])]

而我想把数据转化成

com.browser1 60000 
com.browser1 60000 
com.browser 12075000 
com.browser 12075000 
.......

就是想要把rdd中每行的数组元素变成一行一个. 当然也可以是其他易于分析的结构

因为本人是spark和scala的初学者,所以试了好久都不成功,所以希望大家能指导我一下.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我只土不豪 2022-09-14 16:50:40

没毛病.
根据你的原始的json,如果转换成表结构确实是这个格式,因为json里有两个属性,一个id,一个data,data是个列表,如果你不自己map,spark是不会知道你那个列表映射成表的结构是什么样子的

+--------------------+---+
|                data| id|
+--------------------+---+
|[[60000, com.brow...| 11|
+--------------------+---+

所以如果你想以表的结构展示你的json,需要自己map一下

   val session = SparkSession.builder().config(sc).getOrCreate()
    try {
      val schema = StructType(Seq(
        StructField("id", LongType),
        StructField("package", StringType),
        StructField("activetime", LongType)
      ))

      val encoder = RowEncoder(schema)

      val df = session.read.json("file:\\\\\\E:/anc.json")
        .flatMap(new FlatMapFunction[Row, Row] {
          override def call(r: Row): util.Iterator[Row] = {
            val list = new util.ArrayList[Row]()
            val datas = r.getAs[mutable.WrappedArray.ofRef[Row]]("data")
            datas.foreach(data => {
              list.add(Row(r.getAs[Long]("id"), data.getAs[Long](1), data.getAs[String](0)))
            })
            list.iterator()
          }
        }, encoder)

      df.show()

最后表结构为:

+---+------------+----------+
| id|     package|activetime|
+---+------------+----------+
| 11|com.browser1|     60000|
| 11|com.browser6|   1205000|
| 11|com.browser7|   1205000|
+---+------------+----------+

你也可以在你
sqlContext.sql("SELECT data FROM behavior")
后进行map,关键点在那个列表想怎么展示

浮华 2022-09-14 16:50:40

请问你这个有解决方案了么?

罪歌 2022-09-14 16:50:40

使用EXPLODE函数可以铺平数组

SELECT EXPLODE(data) FROM behavior
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文