如何在scala中映射DataFrame后提取数据

时间:2017-06-23 10:34:20

标签: scala apache-spark dataframe

我是Spark的新手,我试图了解它是如何工作的。 我试图创建一个表(DataFrame),它具有基于我读过的json文件的列。 我所做的是:

val example = mysession.read.json("/FileStore/tables/bm2982090/exampleLog_dp_api-fac53.json")

正如documentation所说,这会返回一个DataFrame。现在,DataFrame看起来像这样:

--------------------+-----------------+------+--------------------+-----+
|                 _id|           _index|_score|             _source|_type|
+--------------------+-----------------+------+--------------------+-----+
|AVzO9dqvoaL5S78GvkQU|dp_api-2017.06.22|     1|[2017-06-22T08:40...|DPAPI|
+--------------------+-----------------+------+--------------------+-----+

正如您所看到的,创建列_id, index等做得很好但是当_source将所有内容放入其中时发生这种情况是因为我看到的文件看起来像红色像这样:

{
  "_index":"dp_api-2017.06.22",
  "_type":"DPAPI",
  "_id":"AVzO9dqvoaL5S78GvkQU",
  "_score":1,
  "_source":{
    "request":{
      "user_ip":"ip",
      "method":"POST",
      "user_agent":"agent",
      "ts":"2017-06-22T10:40:37.420651+02:00"
    },
    "svc":"example",
    "cipher_info":{
      "userdata":[
        "field:parameters.username,start:0,end:0"
      ]
    },
    "message":"{\"class\":\"DPAPI\",\"event\":\"druid.auth.login\",\"operation\":{\"result\":{\"code\":200,\"description\":\"Success\",\"http_status\":200}},\"parameters\":,\"request\":{\"app_instance\":\"e83f99ff-a768-44d2-a448-9b51a535183f-1498034708\",\"end_point\":\"/oken\",\"method\":\"POST\",\"ts\":\"2017-06-22T10:40:37.420651+02:00\",\"user_agent\":\"Dr.1/Sa-SM-N\"},\"svc\":\"c-1\",\"ts\":\"2017-06-22T10:40:37.420614+02:00\"}",
    "type":"DPAPI",
    "tags":[
      "parse_to_json"
    ],
    "index_name":"dp_api",
    "class":"DPAPI",
    "operation":{
      "result":{
        "code":200,
        "description":"Success",
        "http_status":200
      }
    },
    "parameters":{
      "username":"Xp3opAyI0udKPuSQq5gqkQ=="
    },
    "event_age":0.37999987602233887,
    "ts":"2017-06-22T10:40:37.420614+02:00"
  }
}

所以我认为当谈到嵌套值时,过程就是"懒惰"并且它没有正确创建列。我的问题是:在创建DataFrame之前是否可以提取_source的内容?或者在创建数据帧之后执行它很好,但输出应该看起来像我有一个表,其中包含与键一样多的列。 例如:

--------------------+-----------------+------+--------------------+-----+
|                 _id|           _index|_score| _source.request.user_ip|_type|
+--------------------+-----------------+------+--------------------+-----+
|AVzO9dqvoaL5S78GvkQU|dp_api-2017.06.22|     1|ip              |DPAPI|
+--------------------+-----------------+------+--------------------+-----+
希望我解释得很好!谢谢

1 个答案:

答案 0 :(得分:2)

我认为在您创建dataframe之前创建dataframe后提取应该比提取更有效,更快。

您已使用inbuilt functionsAPIs从json创建dataframe。如果您在此之前提取,那么您必须自己编写一些自定义APIs,这不会像提供的APIs一样有效。

创建select后,您只需columns dataframe

example.select("_id", "_index", "_score", "_source.request.user_ip", "_type").show(false)

哪个应该根据您的需要提供dataframe

+--------------------+-----------------+------+-------+-----+
|_id                 |_index           |_score|user_ip|_type|
+--------------------+-----------------+------+-------+-----+
|AVzO9dqvoaL5S78GvkQU|dp_api-2017.06.22|1     |ip     |DPAPI|
+--------------------+-----------------+------+-------+-----+

我希望我能很好地回答你的问题。