簡體   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