繁体   English   中英

如何在Java中使用Apache Beam ParDo函数读取JSON文件

[英]How to read a JSON file using Apache beam parDo function in Java

我是Apache Beam的新手。 根据我们的要求,我需要传递一个包含5至10条JSON记录的JSON文件作为输入,并逐行从文件中读取此JSON数据并存储到BigQuery中。 谁能帮我提供下面的示例代码,该示例代码尝试使用apache beam读取JSON数据:

PCollection<String> lines = 
    pipeline
      .apply("ReadMyFile", 
             TextIO.read()
                   .from("C:\\Users\\Desktop\\test.json")); 
if(null!=lines) { 
  PCollection<String> words =
     lines.apply(ParDo.of(new DoFn<String, String>() { 
        @ProcessElement
        public void processElement(ProcessContext c) { 
          String line = c.element();
        }
      })); 
  pipeline.run(); 
}

答案是取决于。

TextIO读取文件。 因此,在test.json每一行都需要包含一个单独的Json对象。

然后,您拥有的ParDo将一一收到这些行,即,对@ProcessElement每次调用都将获得一行。

然后在你的ParDo ,你可以使用像杰克逊ObjectMapper从线(或任何其他JSON分析器你熟悉解析JSON,但杰克逊被广泛使用,其中包括梁本身几个地方。

总体而言,编写ParDo的方法是:

  • 得到c.element() ;
  • c.element()的值做一些事情,例如将其从json解析为java对象;
  • 将您对c.element()所做的结果发送到c.output() ;

我建议从Beam SDK的Jackson扩展开始,它添加了PTransforms来做到这一点,请参见thisthis

也请看看这篇文章,它有一些链接。

您还可以使用JsonToRow转换来寻找类似的逻辑,不同之处在于它不是将Json解析为用户定义的Java对象,而是解析为Beam Row类。

在写入BQ之前,您需要将从Json解析的对象转换为BQ行,这将是解析逻辑之后的另一个ParDo ,然后实际应用BQIO作为下一步。 您可以在BQ测试中看到一些示例。

假设我们在文件中有一个json字符串,如下所示,

{"col1":"sample-val-1", "col2":1.0}
{"col1":"sample-val-2", "col2":2.0}
{"col1":"sample-val-3", "col2":3.0}
{"col1":"sample-val-4", "col2":4.0}
{"col1":"sample-val-5", "col2":5.0}

为了通过DataFlow / Beam将这些值从文件存储到BigQuery,您可能必须执行以下步骤,

  • 定义一个TableReference来引用BigQuery表。

  • 为您希望存储的每一列定义TableFieldSchema。

  • 使用TextIO.read()读取文件。

  • 创建一个DoFn将Json字符串解析为TableRow格式。

  • 使用BigQueryIO提交TableRow对象。

您可以参考以下有关上述步骤的代码段,

  • 对于TableReference和TableFieldSchema创建,

     TableReference tableRef = new TableReference(); tableRef.setProjectId("project-id"); tableRef.setDatasetId("dataset-name"); tableRef.setTableId("table-name"); List<TableFieldSchema> fieldDefs = new ArrayList<>(); fieldDefs.add(new TableFieldSchema().setName("column1").setType("STRING")); fieldDefs.add(new TableFieldSchema().setName("column2").setType("FLOAT")); 
  • 对于管道步骤,

     Pipeline pipeLine = Pipeline.create(options); pipeLine .apply("ReadMyFile", TextIO.read().from("path-to-json-file")) .apply("MapToTableRow", ParDo.of(new DoFn<String, TableRow>() { @ProcessElement public void processElement(ProcessContext c) { Gson gson = new GsonBuilder().create(); HashMap<String, Object> parsedMap = gson.fromJson(c.element().toString(), HashMap.class); TableRow row = new TableRow(); row.set("column1", parsedMap.get("col1").toString()); row.set("column2", Double.parseDouble(parsedMap.get("col2").toString())); c.output(row); } })) .apply("CommitToBQTable", BigQueryIO.writeTableRows() .to(tableRef) .withSchema(new TableSchema().setFields(fieldDefs)) .withCreateDisposition(CreateDisposition.CREATE_IF_NEEDED) .withWriteDisposition(WriteDisposition.WRITE_APPEND)); pipeLine.run(); 

BigQuery表可能如下所示,

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM