【问题标题】:create JSON schema using StructType in Apacke Spark在 Apache Spark 中使用 StructType 创建 JSON 模式
【发布时间】:2019-12-24 23:28:56
【问题描述】:

我正在尝试为以下 JSON 创建 StructType Schema

{ 
   "countries":{ 
      "country":[ 
         { 
            "area":9596960,
            "cities":{ 

            },
            "name":"China",
            "population":1210004992
         },
         { 
            "area":3287590,
            "cities":{ 

            },
            "name":"India",
            "population":952107712
         },
         { 
            "area":9372610,
            "cities":{ 
               "city":[ 
                  { 
                     "name":"New York",
                     "population":7380906
                  },
                  { 
                     "name":"Los Angeles",
                     "population":3553638
                  },
                  { 
                     "name":"Chicago",
                     "population":2721547
                  },
                  { 
                     "name":"Detroit",
                     "population":1000272
                  }
               ]
            },
            "name":"United States",
            "population":266476272
         },
         { 
            "area":1919440,
            "cities":{ 
               "city":[ 
                  { 
                     "name":"Jakarta",
                     "population":8259266
                  },
                  { 
                     "name":"Surabaya",
                     "population":2483871
                  },
                  { 
                     "name":"Bandung",
                     "population":2058649
                  },
                  { 
                     "name":"Medan",
                     "population":1730752
                  },
                  { 
                     "name":"Semarang",
                     "population":1250971
                  },
                  { 
                     "name":"Palembang",
                     "population":1144279
                  }
               ]
            },
            "name":"Indonesia",
            "population":206611600
         }
      ]
   }
}

我正在执行以下代码来获取所有国家/地区的名称

DataTypes.createStructField("countries", (new StructType()).add(DataTypes.createStructField("country",
                    (new StructType()).add(DataTypes.createStructField("name", DataTypes.StringType, true)), true)), true)

但是当我在下面运行以获取所有国家/地区名称时

Dataset<Row> namesDF = spark.sql("SELECT countries FROM country");
        namesDF.show();

我收到nulls,请问如何使用 StructType 解析 Json 字段以获取值..?

正在做的事情,这是正确的做法吗..?我正在尝试从 JSON 上方获取国家/地区名称

更新:

代码:

    static final StructType SCHEMA = new StructType(new StructField[] {

            DataTypes.createStructField("countries",
                    new StructType().add(DataTypes.createStructField("country",
                            new ArrayType(new StructType()
                                    .add(DataTypes.createStructField("name", DataTypes.StringType, true)), true),
                            true)),
                    true) }

    );

}

入口点

Dataset<Row> ds = spark.read().schema(Jsonreadystructure.SCHEMA)
                .json(context.getProperty(GlobalConstants.ReadyJsonFile));

        ds.printSchema();

        ds.createOrReplaceTempView("country_data");
        ds.sqlContext().sql("SELECT country.name FROM country_data lateral view explode(countries.country) t as country").show(false);

输出

root
 |-- countries: struct (nullable = true)
 |    |-- country: array (nullable = true)
 |    |    |-- element: struct (containsNull = true)
 |    |    |    |-- name: string (nullable = true)

+----+
|name|
+----+
+----+

为什么它显示空名称..?我正在使用火花 2.4.4

架构发现

root
 |-- countries: struct (nullable = true)
 |    |-- country: array (nullable = true)
 |    |    |-- element: struct (containsNull = true)
 |    |    |    |-- area: double (nullable = true)
 |    |    |    |-- cities: struct (nullable = true)
 |    |    |    |    |-- city: string (nullable = true)
 |    |    |    |-- name: string (nullable = true)
 |    |    |    |-- population: long (nullable = true)

【问题讨论】:

    标签: java apache-spark


    【解决方案1】:

    在您的 json country 字段中包含数组而不是结构,因此会导致架构不匹配。您应该像这样使用ArrayType 创建架构:

    DataTypes.createStructField("countries", 
        new StructType().add(DataTypes.createStructField("country",
                        new ArrayType(new StructType().add(DataTypes.createStructField("name", 
        DataTypes.StringType, true)), true), true)), true)
    

    使用此架构,您将获得如下国家/地区:

    df.registerTempTable("country_data");
    spark.sql("SELECT countries FROM country_data").show();
    +--------------------------------------------------------------+
    |countries                                                     |
    +--------------------------------------------------------------+
    |[WrappedArray([China], [India], [United States], [Indonesia])]|
    +--------------------------------------------------------------+
    

    如果您想列出数组中的所有国家/地区,您应该使用explode

    spark.sql("SELECT country.name FROM country_data lateral view explode(countries.country) t as country").show(false)
    +-------------+
    |name         |
    +-------------+
    |China        |
    |India        |
    |United States|
    |Indonesia    |
    +-------------+
    

    【讨论】:

    • 它在输出中没有显示任何条目,请检查有问题的更新。
    • 什么是GlobalConstants.ReadyJsonFile?您的文件是否包含格式精美的 json(如您的帖子中所示)或包含单行 json?
    • 问题是我的 JSON 不是单行 JSON,这就是它失败的原因。请问我可以知道,为什么会这样..?
    • 你能检查一下这个问题吗stackoverflow.com/questions/59466021/…我几乎完成了提取但卡在一个嵌套元素中
    • @JonLe 你的代码看起来很复杂。为什么不使用模式发现?我的意思是val schema = spark.read.json(Seq(json).toDS.rdd).schema.json 而不是org.apache.spark.sql.types.DataType.fromJson(schema)?
    猜你喜欢
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 2020-02-26
    • 2019-11-26
    • 2021-01-08
    • 1970-01-01
    • 2016-10-29
    • 1970-01-01
    相关资源
    最近更新 更多