次のように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はアプリのアクティベーション時間であり、その目的は各アプリの合計アクティベーション時間を分析することです。
sparK SQLを使用してJSONを解析します
scala
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 query
appActiveTime.show (100100) // print dataFrame
appActiveTime.rdd.foreach(println) // print 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の各行の配列要素を1つの行に変換したいと思います。もちろん、分析しやすい別の構造にすることもできます。
私はsparkとScalaをたくさん学ぶだけなので、長い間試してきましたが失敗しました。ご案内いただければ幸いです。
指定されたjson
データから、dataframe
とprintSchema
のスキーマを表示して使用できます。
appActiveTime.printSchema()
root
|-- data: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- activetime: long (nullable = true)
| | |-- package: string (nullable = true)
array
があるので、データをexplode
して、以下のように構造体フィールドを選択する必要があります。
import org.Apache.spark.sql.functions._
appActiveTime.withColumn("data", explode($"data"))
.select("data.*")
.show(false)
出力:
+----------+------------+
|activetime| package|
+----------+------------+
| 60000|com.browser1|
| 1205000|com.browser6|
| 1205000|com.browser7|
| 60000|com.browser1|
| 1205000|com.browser6|
+----------+------------+
お役に立てれば!
@Shankar Koiralaの助けを借りて、「explode」を使用してjson配列を処理する方法を学びました。
val df = sqlContext.sql("SELECT data FROM behavior")
appActiveTime.select(explode(df("data"))).toDF("data")
.select("data.package","data.activetime")
.show(false)