全部產品
Search
文件中心

E-MapReduce:JSON格式匯入

更新時間:Jul 01, 2024

Doris支援匯入JSON格式的資料。本文為您介紹進行JSON格式資料匯入時的參數說明和注意事項。

支援的匯入方式

目前只有以下匯入方式支援JSON格式的資料匯入:

  • 將本地JSON格式的檔案通過Stream Load方式匯入。

  • 通過Routine Load訂閱並消費Kafka中的JSON格式訊息。

說明

暫不支援其他方式的JSON格式資料匯入。

支援的JSON格式

當前僅支援以下兩種JSON格式:

  • 以Array表示的多行資料

    以Array為根節點的JSON格式。Array中的每個元素表示要匯入的一行資料,通常是一個Object。樣本如下:

    [
        { "id": 123, "city" : "beijing"},
        { "id": 456, "city" : "shanghai"},
        ...
    ]

    這種方式通常用於Stream Load匯入方式,以便在一批匯入資料中表示多行資料。

    重要

    必須配合設定strip_outer_array=true使用。Doris在解析時會將數組展開,然後依次解析其中的每一個 Object作為一行資料。

  • 以Object表示的單行資料

    以Object為根節點的JSON格式。整個Object即表示要匯入的一行資料。樣本如下:

    { "id": 123, "city" : "beijing"}
    { "id": 123, "city" : { "name" : "beijing", "region" : "haidian" }}

    這種方式通常用於Routine Load匯入方式,如表示Kafka中的一條訊息,即一行資料。

  • 以固定分隔字元分隔的多行Object資料

    Object表示的一行資料,即表示要匯入的一行資料,樣本如下:

    { "id": 123, "city" : "beijing"}
    { "id": 456, "city" : "shanghai"}
    ...

    這種方式通常用於Stream Load匯入方式,以便在一批匯入資料中表示多行資料。

    重要

    必須配合設定read_json_by_line=true使用,特殊分隔字元還需要指定line_delimiter參數,預設\n。Doris在解析時會按照分隔字元分隔,然後解析其中的每一行Object作為一行資料。

JSON參數

  • streaming_load_json_max_mb參數

    • 一些資料格式,如JSON,無法進行拆分處理,必須讀取全部資料到記憶體後才能開始解析,因此,這個值用於限制此類格式資料單次匯入最巨量資料量。

    • 預設值為100,單位MB,詳情請參見BE參數配置修改此參數。

  • fuzzy_parse參數

    • Stream Load中,可以添加fuzzy_parse參數來加速JSON資料的匯入效率。

    • 這個參數通常用於匯入以Array表示的多行資料這種格式,所以一般要配合strip_outer_array=true使用。

    • 這個功能要求Array中的每行資料的欄位順序完全一致。Doris僅會根據第一行的欄位順序做解析,然後以下標的形式訪問之後的資料,該方式可以提升3~5倍的匯入效率。

JSON Path

Doris支援通過JSON Path抽取JSON中指定的資料。

說明

因為對於Array類型的資料,Doris會先進行數組展開,最終按照Object格式進行單行處理,故以單個Object格式的JSON資料進行如下說明。

  • 不指定JSON Path

    如果沒有指定JSON Path,則Doris會預設使用表中的列名尋找Object中的元素。樣本如下:

    表中包含兩列id, city。Json資料如下:

    { "id": 123, "city" : "beijing"}

    則Doris會使用id, city進行匹配,得到最終資料123beijing

    若JSON資料如下:

    { "id": 123, "name" : "beijing"}

    則Doris使用id, city進行匹配,得到最終資料123null

  • 指定JSON Path

    通過一個JSON資料的形式指定一組JSON Path。數組中的每個元素表示一個要抽取的列。樣本如下:

    ["$.id", "$.name"]
    ["$.id.sub_id", "$.name[0]", "$.city[0]"]

    Doris會使用指定的JSON Path進行資料匹配和抽取。

  • 匹配非基本類型

    前面的樣本最終匹配到的數值都是基本類型,如整型、字串等。Doris當前暫不支援複合類型,如Array、Map等。所以當匹配到一個非基本類型時,Doris會將該類型轉換為JSON格式的字串,並以字串類型進行匯入,樣本如下:

    JSON資料為:

    { "id": 123, "city" : { "name" : "beijing", "region" : "haidian" }}

    JSON Path為["$.city"]。則匹配到的元素為:

    { "name" : "beijing", "region" : "haidian" }

    該元素會被轉換為字串進行後續匯入操作:

    "{'name':'beijing','region':'haidian'}"
  • 匹配失敗

    當匹配失敗時,將會返回Null。樣本如下:

    JSON資料為:

    { "id": 123, "name" : "beijing"}

    JSON Path為["$.id", "$.info"]。則匹配到的元素為123null

    Doris當前不區分JSON資料中表示的Null值,和匹配失敗時產生的Null值。假設JSON資料為:

    { "id": 123, "name" : null }

    則使用以下兩種JSON Path會獲得相同的結果:123null

    • ["$.id", "$.name"]
    • ["$.id", "$.info"]
  • 完全符合失敗

    為防止一些參數設定錯誤導致的誤操作。Doris在嘗試匹配一行資料時,如果所有列都匹配失敗,則會認為這個是一個錯誤行。假設JSON資料為:

    { "id": 123, "city" : "beijing" }

    如果JSON Path錯誤的寫為(或者不指定JSON Path時,表中的列不包含idcity):

    ["$.ad", "$.infa"]

    則會導致完全符合失敗,則該行會標記為錯誤行,而不是產出null, null

JSON Path和Columns

JSON Path用於指定如何對JSON格式中的資料進行抽取,而Columns指定列的映射和轉換關係。兩者可以配合使用。

相當於通過JSON Path,將一個JSON格式的資料,按照JSON Path中指定的列順序進行了列的重排。之後,可以通過Columns,將這個重排後的來源資料和表的列進行映射。舉例如下:

  • 資料內容

    {"k1" : 1, "k2": 2}
  • 表結構

    k2 int, k1 int
  • 匯入語句1(以Stream Load為例)

    curl -v --location-trusted -u root: -H "format: json" -H "jsonpaths: [\"$.k2\", \"$.k1\"]" -T example.json http://127.0.0.1:8030/api/db1/tbl1/_stream_load

    匯入語句1中,僅指定了JSON Path,沒有指定Columns。其中JSON Path的作用是將JSON資料按照JSON Path中欄位的順序進行抽取,之後會按照表結構的順序進行寫入。最終匯入的資料結果如下:

    +------+------+
    | k1   | k2   |
    +------+------+
    |    2 |    1 |
    +------+------+

    實際的k1列匯入了JSON資料中的k2列的值。因為JSON中欄位名稱並不等同於表結構中欄位的名稱,所以需要顯式的指定這兩者之間的映射關係。

  • 匯入語句2

    curl -v --location-trusted -u root: -H "format: json" -H "jsonpaths: [\"$.k2\", \"$.k1\"]" -H "columns: k2, k1" -T example.json http://127.0.0.1:8030/api/db1/tbl1/_stream_load

    相比如匯入語句1,這裡增加了Columns欄位,用於描述列的映射關係,按k2,k1的順序。即按JSON Path中欄位的順序抽取後,指定第一列為表中k2列的值,而第二列為表中k1列的值。最終匯入的資料結果如下:

    +------+------+
    | k1   | k2   |
    +------+------+
    |    1 |    2 |
    +------+------+

    如其他匯入一樣,可以在Columns中進行列的轉換操作。樣本如下:

    curl -v --location-trusted -u root: -H "format: json" -H "jsonpaths: [\"$.k2\", \"$.k1\"]" -H "columns: k2, tmp_k1, k1 = tmp_k1 * 100" -T example.json http://127.0.0.1:8030/api/db1/tbl1/_stream_load

    上述樣本會將k1的值乘以100後匯入。最終匯入的資料結果如下:

    +------+------+
    | k1   | k2   |
    +------+------+
    |  100 |    2 |
    +------+------+

JSON Root

Doris支援通過JSON Root抽取JSON中指定的資料。

說明

對於Array類型的資料,Doris會先進行數組展開,最終按照Object格式進行單行處理。所以樣本都以單個Object格式的JSON資料進行說明。

  • 不指定JSON Root

    如果沒有指定JSON Root,則Doris會預設使用表中的列名尋找Object中的元素。樣本如下:

    表中包含兩列:idcity。JSON資料為:

    { "id": 123, "name" : { "id" : "321", "city" : "shanghai" }}

    則Doris會使用id, city進行匹配,得到最終資料123null

  • 指定JSON Root

    通過JSON_Root指定JSON資料的根節點。Doris將通過JSON Root抽取根節點的元素進行解析。預設為空白。

    指定Json root -H "json_root: $.name"。則匹配到的元素為:

    { "id" : "321", "city" : "shanghai" }

    該元素會被當作新JSON進行後續匯入操作,得到最終資料321shanghai

NULL和Default值

  • 樣本資料如下:

    [
        {"k1": 1, "k2": "a"},
        {"k1": 2},
        {"k1": 3, "k2": "c"},
    ]

    表結構為:k1 int null, k2 varchar(32) null default "x"

  • 匯入語句如下:

    curl -v --location-trusted -u root: -H "format: json" -H "strip_outer_array: true" -T example.json http://127.0.0.1:8030/api/db1/tbl1/_stream_load

    您可能期望的匯入結果如下,即對於缺失的列,填寫預設值。

    +------+------+
    | k1   | k2   |
    +------+------+
    |    1 |    a |
    +------+------+
    |    2 |    x |
    +------+------+
    |    3 |    c |
    +------+------+

    但實際的匯入結果如下,即對於缺失的列,補上了NULL。

    +------+------+
    | k1   | k2   |
    +------+------+
    |    1 |    a |
    +------+------+
    |    2 | NULL |
    +------+------+
    |    3 |    c |
    +------+------+

    這是因為通過匯入語句中的資訊,Doris並未擷取“缺失的列是表中的k2列”的資訊。如果要對以上資料按照期望結果匯入,則匯入語句如下:

    curl -v --location-trusted -u root: -H "format: json" -H "strip_outer_array: true" -H "jsonpaths: [\"$.k1\", \"$.k2\"]" -H "columns: k1, tmp_k2, k2 = ifnull(tmp_k2, 'x')" -T example.json http://127.0.0.1:8030/api/db1/tbl1/_stream_load