如何将结构化数据映射到Spark中的schemaRDD?

时间:2015-03-06 00:31:20

标签: python json apache-spark apache-spark-sql

我以前对这个问题的看法不同,但有一些变化,所以我想再把它作为一个新问题。 我有一个结构化数据,其中只有一部分是json格式,但我需要将整个数据映射到schemaRDD。数据如下所示:

  

03052015 04:13:20   {" RECORDTYPE":" NEW""数据" {" KEYCOL":" VAL1"&#34 ; COL2":" val2的"" COL3":" VAL3"}

每行以日期后跟时间和json格式的文本开头。 我不仅要将json中的文本映射到同一个结构中,还要映射到日期和时间。

我在Python中尝试过,但显然它不起作用,因为Row没有采用RDD(在这种情况下是jsonRDD)。

    from pyspark.sql import SQLContext, Row
    sqlContext = SQLContext(sc)
    orderFile  = sc.textFile(myfile)
    orderLine  = orderFile.map(lambda line: line.split(" ", 2))
    anotherOrderLine = orderLine.map(lambda p: Row(date=p[0], time=p[1], content=sqlContext.jsonRDD(p[3])))
    schemaOrder = sqlContext.inferSchema(anotherOrderLine)
    schemaOrder.printSchema()
    for x in schemaOrder.collect():
        print x

目标是能够针对schemaRDD运行这样的查询:

select date, time, data.keycol, data.val1, data.val2, data.val3 from myOrder

如何将整行映射到schemaRDD?

感谢任何帮助?

2 个答案:

答案 0 :(得分:0)

sqlContext.jsonRDD从包含字符串的RDD创建模式rdd,其中每个字符串包含JSON表示。此代码示例来自SparkSQL文档(https://spark.apache.org/docs/1.2.0/sql-programming-guide.html):

val anotherPeopleRDD = sc.parallelize("""{"name":"Yin","address":{"city":"Columbus","state":"Ohio"}}""" :: Nil)
val anotherPeople = sqlContext.jsonRDD(anotherPeopleRDD)

关于jsonRDD的一个很酷的事情是,您可以提供和附加说明JSON模式的参数,这可以提高性能。这可以通过创建schemaRDD(只是加载示例文档)然后调用schemaRDD.schema方法来获取模式。

答案 1 :(得分:0)

最简单的选择是将此字段添加到JSON并使用jsonRDD

我的数据:

03052015 04:13:20 {"recordType":"NEW","data":{"keycol":"val1","col1":"val5","col2":"val3"}}
03062015 04:13:20 {"recordType":"NEW1","data":{"keycol":"val2","col1":"val6","col2":"val3"}}
03072015 04:13:20 {"recordType":"NEW2","data":{"keycol":"val3","col1":"val7","col2":"val3"}}
03082015 04:13:20 {"recordType":"NEW3","data":{"keycol":"val4","col1":"val8","col2":"val3"}}

代码:

import json

def transform(data):
    ts  = data[:18].strip()
    jss = data[18:].strip()
    jsj = json.loads(jss)
    jsj['ts'] = ts
    return json.dumps(jsj)

from pyspark.sql import SQLContext
sqlContext = SQLContext(sc)
rdd = sc.textFile('/sparkdemo/sample.data')
tbl = sqlContext.jsonRDD(rdd.map(transform))
tbl.registerTempTable("myOrder")

sqlContext.sql("select ts, recordType, data.keycol, data.col1, data.col2 data from myOrder").collect()

结果:

[Row(ts=u'03052015 04:13:20', recordType=u'NEW', keycol=u'val1', col1=u'val5', data=u'val3'), Row(ts=u'03062015 04:13:20', recordType=u'NEW1', keycol=u'val2', col1=u'val6', data=u'val3'), Row(ts=u'03072015 04:13:20', recordType=u'NEW2', keycol=u'val3', col1=u'val7', data=u'val3'), Row(ts=u'03082015 04:13:20', recordType=u'NEW3', keycol=u'val4', col1=u'val8', data=u'val3')]

在你的代码中有一个问题,就是你为每一行调用jsonRDD,这是不正确的 - 它接受一个RDD并返回SchemaRDD。