代码之家  ›  专栏  ›  技术社区  ›  Punith Raj

spark xml中具有嵌套父节点的自定义架构

  •  1
  • Punith Raj  · 技术社区  · 6 年前

    我对spark xml非常陌生,我发现很难为我的对象准备自定义模式。请大家帮助我。下面是我尝试过的。

    我使用的是Spark 1.4.7和Spark xml版本0.3.5

    测验Java语言

    StructType customSchema = new StructType(new StructField[]{
        new StructField("id", DataTypes.StringType, true, Metadata.empty()),
        new StructField("name", DataTypes.StringType, true, Metadata.empty()),
    
        DataTypes.createStructField("names", DataTypes.createStructType(new StructField[]{
            DataTypes.createStructField("test", DataTypes.createArrayType(DataTypes.StringType),
                true)}), true)
    });
    
    final JavaRDD<Row> map = spoofRDD()
        .map(book -> RowFactory.create(
            book.getId(),
            book.getName(),
            book.getNames()));
    
    final DataFrame df = sqlContext.createDataFrame(map, customSchema);
    df.show();
    df.printSchema();
    
    
    
    private JavaRDD<Book> spoofRDD() {
    
    Book book1 = Book.builder().id("1").name("Name1")
        .names(new String[]{"1", "2"}).build();
    List<Book> books = new ArrayList<>();
    books.add(book1);
    
    return javaSparkContext.parallelize(books);
    }
    

    我的POJO课堂用书。Java语言

    private final String id;
    private final String name;
    private final String[] names;
    

    我的 预期的 XML

    <books>
    <book>
        <id>1</id>
        <name>Name1</name>
        **<parent>**
            <names>1</names>
            <names>2</names>
        **</parent>**
    </book>
    <book>
        <id>2</id>
        <name>Name2</name>
        **<parent>**
            <names>1</names>
            <names>2</names>
        **</parent>**
    </book>
    

    因此,正如您所看到的,我希望在父级中有一个嵌套的标记。如何修改customSchema以实现相同的效果。

    1 回复  |  直到 6 年前
        1
  •  1
  •   zero323 little_kid_pea    6 年前

    所需XML输出的正确模式为:

    root
     |-- id: long (nullable = true)
     |-- name: string (nullable = true)
     |-- parent: struct (nullable = true)
     |    |-- names: array (nullable = true)
     |    |    |-- element: long (containsNull = true)]
    

    当前架构为:

    root
     |-- id: string (nullable = true)
     |-- name: string (nullable = true)
     |-- names: struct (nullable = true)
     |    |-- test: array (nullable = true)
     |    |    |-- element: string (containsNull = true)
    

    所以这里唯一需要更改的是 test name names parent 和数组内容的值类型。

    new StructType(new StructField[]{
      new StructField("id", DataTypes.StringType, true, Metadata.empty()),
      new StructField("name", DataTypes.StringType, true, Metadata.empty()),
    
      DataTypes.createStructField("names", DataTypes.createStructType(new StructField[]{
        DataTypes.createStructField("test", DataTypes.createArrayType(DataTypes.StringType),
            true)}), true)
    })
    

    真正的问题是数据。因为 父母亲 必须是 struct ,则, getNames 输出应包装为 Row :

    .map(book -> RowFactory.create(
        book.getId(),
        book.getName(),
        RowFactory.create(book.getNames())));