Doris は、Stream Load および Routine Load を通じて JSON データのインポートをサポートしています。本トピックでは、サポートされる JSON フォーマット、パラメーター、および JSON パス、カラム、JSON ルートがどのように連携して動作するかについて説明します。
サポートされるインポート方法
JSON データは、以下の 2 つの方法でのみインポートできます。
Stream Load:ローカルの JSON ファイルをインポートします。
Routine Load:Kafka から JSON 形式のメッセージをサブスクライブして消費します。
その他のインポート方法は JSON フォーマットをサポートしていません。
サポートされる JSON フォーマット
ユースケースに応じて JSON フォーマットを選択してください。
| フォーマット | 最適な用途 | 必要なパラメーター |
|---|---|---|
| ルートノードとしての配列 | 複数行を含む Stream Load バッチインポート | strip_outer_array: true |
| ルートノードとしてのオブジェクト | Routine Load(1 つの Kafka メッセージ = 1 行) | なし |
| 改行区切りオブジェクト | NDJSON スタイルの Stream Load バッチインポート | read_json_by_line: true |
ルートノードとしての配列
ルートノードが配列です。各要素が 1 行を表します。
[
{ "id": 123, "city": "beijing" },
{ "id": 456, "city": "shanghai" },
...
]strip_outer_array を true に設定します。Doris は配列を展開し、各オブジェクトを 1 行として解析します。
ルートノードとしてのオブジェクト
単一のオブジェクトが 1 行を表します。
{ "id": 123, "city": "beijing" }ネストされたオブジェクトも有効です。
{ "id": 123, "city": { "name": "beijing", "region": "haidian" } }このフォーマットは通常、Routine Load で使用され、各 Kafka メッセージが 1 行に対応します。
改行区切りオブジェクト
デリミタで区切られた複数のオブジェクトが、1 行につき 1 オブジェクトの形式で記述されます。
{ "id": 123, "city": "beijing" }
{ "id": 456, "city": "shanghai" }
...read_json_by_line を true に設定します。line_delimiter を設定してデリミタを指定してください。デフォルトは \n です。Doris は入力を各デリミタで分割し、各オブジェクトを 1 行として解析します。
JSON パラメーター
以下のパラメーターは JSON インポートの動作を制御します。
| パラメーター | デフォルト | Stream Load | Routine Load | 説明 |
|---|---|---|---|---|
streaming_load_json_max_mb | 100 | streaming_load_json_max_mb | 該当なし | 1 回の Stream Load ジョブあたりの JSON データの最大サイズ (MB)。詳細については、「バックエンドノードの設定項目」をご参照ください。 |
strip_outer_array | false | strip_outer_array | strip_outer_array | 配列のルートノードを展開し、各要素を 1 行として解析します。配列形式の JSON には必須です。 |
read_json_by_line | false | read_json_by_line | サポートされていません | 各行を個別の JSON オブジェクトとして解析します。改行区切り形式の JSON には必須です。 |
jsonpaths | なし | jsonpaths | jsonpaths | 抽出するフィールドとその順序を指定する JSON パス式。 |
json_root | なし | json_root | json_root | さらに解析を行う前に抽出するルートノードを指す JSONPath 式。 |
fuzzy_parse | false | fuzzy_parse | サポートされていません | 配列形式の JSON のインポート効率を向上させます。すべての行のフィールドが同じ順序である必要があります。 |
num_as_string | — | num_as_string | num_as_string | JSON の数値を文字列として解析します。 |
line_delimiter | \n | line_delimiter | 該当なし | 改行区切り形式のデリミタ。read_json_by_line: true と併用します。 |
fuzzy_parse
目的:配列形式の JSON のインポート効率を向上させます。
デフォルト:false
動作:Doris は最初の行のみからフィールドの順序を解析し、以降の行はフィールド名による検索ではなく添字位置でアクセスします。これにより、インポート速度が 3 ~ 5 倍向上します。
制約事項:
Stream Load のみ対応 — Routine Load ではサポートされていません。
配列内のすべての行のフィールドが同じ順序である必要があります。
fuzzy_parseを使用する場合は、strip_outer_arrayをtrueに設定してください。
JSON パス
jsonpaths を使用して、JSON データから特定のフィールドを抽出します。jsonpaths を指定しない場合、Doris はカラム名とフィールド名を照合します。
配列形式の JSON の場合、Doris はまず配列を展開してから各要素を処理します。以下の例は単一オブジェクト形式を使用しています。
jsonpaths を使用しない場合
Doris はカラム名とフィールド名を照合します。カラムが id および city のテーブルがある場合:
{ "id": 123, "city": "beijing" }Doris は id → 123、city → "beijing" と照合します。
フィールドが存在しない場合:
{ "id": 123, "name": "beijing" }Doris は id → 123、city → null(マッチなし)と照合します。
jsonpaths を使用する場合
JSONPath 式の順序付きリストを指定します。各式は 1 つのカラムに対応します。
["$.id", "$.name"]["$.id.sub_id", "$.name[0]", "$.city[0]"]Doris は指定された順序でフィールドを抽出し、テーブルカラムに位置でマッピングします。
非基本データ型
Doris はカラムタイプとして配列またはマップをサポートしていません。マッチした値がオブジェクトまたは配列の場合、Doris はそれを JSON 文字列に変換します。
与えられた:
{ "id": 123, "city": { "name": "beijing", "region": "haidian" } }jsonpaths: ["$.city"] を使用すると、マッチ結果は次のようになります。
{ "name": "beijing", "region": "haidian" }これは以下の文字列として格納されます。
"{'name':'beijing','region':'haidian'}"マッチ失敗
フィールドパスが存在しない場合、Doris は null を返します。Doris はデータ内の null 値とマッチ失敗を区別しません。例:
{ "id": 123, "name": null }["$.id", "$.name"] および ["$.id", "$.info"] の両方が 123 および null を返します。
完全マッチ失敗:すべてのカラムのマッチに失敗した場合、Doris は全カラムが null になる代わりに、その行全体をエラー行としてマークします。例:
{ "id": 123, "city": "beijing" }["$.ad", "$.infa"] のような無効なパスを使用した場合、またはテーブルスキーマに id も city も存在しない場合、Doris はその行をエラー行としてマークします。
JSON パスとカラム
jsonpaths と columns は異なる役割を持ち、順番に適用されます。
`jsonpaths` は JSON ソースからフィールドを抽出し、位置ベースのデータセットに並べ替えます。
`columns` はその位置ベースのデータセットをターゲットテーブルのカラムにマッピングし、必要に応じて変換を適用します。
この分離により、JSON から任意の順序でフィールドを抽出し、テーブルカラムに名前でマッピングできます。
サンプルデータ:
{"k1": 1, "k2": 2}テーブルスキーマ:
k2 int, k1 intインポート文 1 — jsonpaths のみ、columns なし:
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_loadjsonpaths は k2、次に k1 の順で抽出します。columns が指定されていないため、Doris は位置でテーブルスキーマ (k2 int, k1 int) にマッピングし、最初に抽出された値は k2 に、2 番目の値は k1 に割り当てられます。結果:
+------+------+
| k1 | k2 |
+------+------+
| 2 | 1 |
+------+------+JSON の k2 値 (2) が k1 カラムに格納されています。これは、位置マッピングが名前の違いを考慮しないためです。columns を使用してこれを修正できます。
インポート文 2 — jsonpaths と columns の併用:
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_loadjsonpaths は [$.k2, $.k1] → 位置 [0, 1] で抽出します。columns: k2, k1 は位置 0 をカラム k2 に、位置 1 をカラム k1 に名前で割り当てます。結果:
+------+------+
| k1 | k2 |
+------+------+
| 1 | 2 |
+------+------+インポート文 3 — カラム変換:
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_loadcolumns 式は位置 1 を一時カラム tmp_k1 に割り当て、その後 k1 を tmp_k1 * 100 として導出します。結果:
+------+------+
| k1 | k2 |
+------+------+
| 100 | 2 |
+------+------+JSON ルート
json_root を使用して、Doris が解析を開始するルートノードを指定します。これは、JSON ペイロードが実際のデータをネストされた構造内にラップしている場合に便利です。
配列形式の JSON の場合、Doris はまず配列を展開してから各要素を処理します。以下の例は単一オブジェクト形式を使用しています。
json_root を使用しない場合:カラムが id および city のテーブルがある場合:
{ "id": 123, "name": { "id": "321", "city": "shanghai" } }Doris はトップレベルのオブジェクトを検索し、id → 123、city → null とマッチします。
json_root を使用する場合:-H "json_root: $.name" を設定します。Doris は name ノードを抽出します。
{ "id": "321", "city": "shanghai" }これが新しい入力となります。Doris は id → 321、city → "shanghai" とマッチします。
NULL とデフォルト値
JSON 行にカラムが存在しない場合、Doris はデフォルト値ではなく null を書き込みます。デフォルト値を適用するには、jsonpaths および columns を使用して明示的な式を指定してください。
サンプルデータ:
[
{"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結果 — 存在しない k2 値はデフォルト値 "x" ではなく NULL になります。
+------+------+
| k1 | k2 |
+------+------+
| 1 | a |
+------+------+
| 2 | NULL |
+------+------+
| 3 | c |
+------+------+Doris はコンテキストからどのテーブルカラムが欠落しているかを判断できないため、null を書き込みます。デフォルト値を適用するには、カラムを明示的に参照し、ifnull を使用してください。
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_loadjsonpaths は k2 を tmp_k2 に抽出します。tmp_k2 が null(フィールドが存在しない)の場合、ifnull が 'x' に置き換えます。結果:
+------+------+
| k1 | k2 |
+------+------+
| 1 | a |
+------+------+
| 2 | x |
+------+------+
| 3 | c |
+------+------+