在Spark中合并seq json hdfs文件中的重复列

时间:2019-01-19 19:37:40

标签: apache-spark apache-spark-sql

我正在使用这样的火花从HDFS读取seq json文件:

val data = spark.read.json(spark.sparkContext.sequenceFile[String, String]("/prod/data/class1/20190114/2019011413/class2/part-*").map{
    case (x,y) => 
    (y.toString)})

data.registerTempTable("data")

val filteredData = data.filter("sourceInfo='Web'")

val explodedData = filteredData.withColumn("A", explode(filteredData("payload.adCsm.vfrd")))
val explodedDataDbg = explodedData.withColumn("B", explode(filteredData("payload.adCsm.dbg"))).drop("payload")

出现此错误的原因:

org.apache.spark.sql.AnalysisException: 
Ambiguous reference to fields StructField(adCsm,ArrayType(StructType(StructField(atfComp,StringType,true), StructField(csmTot,StringType,true), StructField(dbc,ArrayType(LongType,true),true), StructField(dbcx,LongType,true), StructField(dbg,StringType,true), StructField(dbv,LongType,true), StructField(fv,LongType,true), StructField(hdr,LongType,true), StructField(hidden,StructType(StructField(duration,LongType,true), StructField(stime,StringType,true)),true), StructField(hvrx,DoubleType,true), StructField(hvry,DoubleType,true), StructField(inf,StringType,true), StructField(isP,LongType,true), StructField(ltav,StringType,true), StructField(ltdb,StringType,true), StructField(ltdm,StringType,true), StructField(lteu,StringType,true), StructField(ltfm,StringType,true), StructField(ltfs,StringType,true), StructField(lths,StringType,true), StructField(ltpm,StringType,true), StructField(ltpq,StringType,true), StructField(ltts,StringType,true), StructField(ltut,StringType,true), StructField(ltvd,StringType,true), StructField(ltvv,StringType,true), StructField(msg,StringType,true), StructField(nl,LongType,true), StructField(prerender,StructType(StructField(duration,LongType,true), StructField(stime,LongType,true)),true), StructField(pt,StringType,true), StructField(src,StringType,true), StructField(states,StringType,true), StructField(tdr,StringType,true), StructField(tld,StringType,true), StructField(trusted,BooleanType,true), StructField(tsc,LongType,true), StructField(tsd,DoubleType,true), StructField(tsz,DoubleType,true), StructField(type,StringType,true), StructField(unloaded,StructType(StructField(duration,LongType,true), StructField(stime,LongType,true)),true), StructField(vdr,StringType,true), StructField(vfrd,LongType,true), StructField(visible,StructType(StructField(duration,LongType,true), StructField(stime,StringType,true)),true), StructField(xpath,StringType,true)),true),true), StructField(adcsm,ArrayType(StructType(StructField(tdr,DoubleType,true), StructField(vdr,DoubleType,true)),true),true);

不确定如何,但有时在“有效载荷”中有两个结构的名称为“ adCsm”。由于我对其中之一存在的领域感兴趣,因此我需要处理这种歧义。

我知道一种方法是检查字段A和B,如果字段不存在则删除该列,因此选择另一个adCsm。想知道是否有更好的方法来解决这个问题?是否可以合并重复的列(具有不同的数据),而不是进行此显式过滤? 不知道在seq“ json”文件中如何存在重复的结构 TIA!

1 个答案:

答案 0 :(得分:1)

我认为,由于Spark数据帧列名称中的大小写敏感问题而导致歧义发生。在模式的最后一部分,我看到

StructField(adcsm,
ArrayType(StructType(
StructField(tdr,DoubleType,true), 
StructField(vdr,DoubleType,true)),true),true)

因此,adScm StructType中有两个同名的structFields(adscmplain)。 首先通过以下方式启用spark sql的区分大小写:

sqlContext.sql("set spark.sql.caseSensitive=true")

然后它将区分这两个字段。以下是解决大小写敏感问题solve case sensitivity issue 的详细信息。希望它将对您有所帮助。