リモートストレージシステム(S3、HDFS、およびその他のS3互換オブジェクトストレージ)からファイルにアクセスする際、Dorisはワイルドカードや範囲表現を含む柔軟なファイルパスパターンをサポートします。このドキュメントでは、サポートされるパス形式とパターンマッチング構文について説明します。
これらのパスパターンは以下でサポートされています:
| 形式 | フォーマット | 例 |
|---|---|---|
| AWS Client Style (Hadoop S3) | s3://bucket/path/to/file | s3://my-bucket/data/file.csv |
| S3A Style | s3a://bucket/path/to/file | s3a://my-bucket/data/file.csv |
| S3N Style | s3n://bucket/path/to/file | s3n://my-bucket/data/file.csv |
| Virtual Host Style | https://bucket.endpoint/path/to/file | https://my-bucket.s3.us-west-1.amazonaws.com/data/file.csv |
| Path Style | https://endpoint/bucket/path/to/file | https://s3.us-west-1.amazonaws.com/my-bucket/data/file.csv |
| プロバイダー | スキーム | 例 |
|---|---|---|
| Alibaba Cloud OSS | oss:// | oss://my-bucket/data/file.csv |
| Tencent Cloud COS | cos://, cosn:// | cos://my-bucket/data/file.csv |
| Baidu Cloud BOS | bos:// | bos://my-bucket/data/file.csv |
| Huawei Cloud OBS | obs:// | obs://my-bucket/data/file.csv |
| Google Cloud Storage | gs:// | gs://my-bucket/data/file.csv |
| Azure Blob Storage | azure:// | azure://container/data/file.csv |
| 形式 | フォーマット | 例 |
|---|---|---|
| 標準 | hdfs://namenode:port/path/to/file | hdfs://namenode:8020/user/data/file.csv |
| HAモード | hdfs://nameservice/path/to/file | hdfs://my-ha-cluster/user/data/file.csv |
Dorisはファイルパスにglob形式のパターンマッチングを使用します。以下のワイルドカードがサポートされています:
| パターン | 説明 | 例 | マッチするもの |
|---|---|---|---|
* | パスセグメント内の0文字以上の文字にマッチ | *.csv | file.csv、data.csv、a.csv |
? | 正確に1文字にマッチ | file?.csv | file1.csv、fileA.csvだがfile10.csvはマッチしない |
[abc] | ブラケット内の任意の1文字にマッチ | file[123].csv | file1.csv、file2.csv、file3.csv |
[a-z] | 範囲内の任意の1文字にマッチ | file[a-c].csv | filea.csv、fileb.csv、filec.csv |
[!abc] | ブラケット内にない任意の1文字にマッチ | file[!0-9].csv | filea.csv、fileb.csvだがfile1.csvはマッチしない |
Dorisはブレースパターン{start..end}を使用した数値範囲展開をサポートします:
| パターン | 展開 | マッチするもの |
|---|---|---|
{1..3} | {1,2,3} | 1、2、3 |
{01..05} | {1,2,3,4,5} | 1、2、3、4、5(先頭のゼロは保持されない) |
{3..1} | {1,2,3} | 1、2、3(逆順範囲がサポートされる) |
{a,b,c} | {a,b,c} | a、b、c(列挙) |
{1..3,5,7..9} | {1,2,3,5,7,8,9} | 範囲と値の混在 |
:::caution 注意
file_{a..b,-1..3,4..5}はfile_4とfile_5にマッチします(無効なa..bと負の範囲-1..3はスキップされますが、4..5は正常に展開されます)。{-1..2})、その範囲はスキップされます。有効な範囲と混在している場合(例:{-1..2,1..3})、有効な範囲1..3のみが展開されます。{1..4,a}では、非数値のaは無視され、結果として{1,2,3,4}になります。{a,b,c}のような純粋な列挙パターン(..範囲を含まない)は直接glob マッチングに渡され、期待通りに動作します。 :::複数のパターンを1つのパスに組み合わせることができます:
s3://bucket/data_{1..3}/file_*.csv
これは以下にマッチします:
s3://bucket/data_1/file_a.csvs3://bucket/data_1/file_b.csvs3://bucket/data_2/file_a.csvディレクトリ内のすべてのCSVファイルにマッチ:
SELECT * FROM S3( "uri" = "s3://my-bucket/data/*.csv", "s3.access_key" = "xxx", "s3.secret_key" = "xxx", "s3.region" = "us-east-1", "format" = "csv" );
数値範囲でファイルをマッチ:
SELECT * FROM S3( "uri" = "s3://my-bucket/logs/data_{1..10}.csv", "s3.access_key" = "xxx", "s3.secret_key" = "xxx", "s3.region" = "us-east-1", "format" = "csv" );
日付でパーティション分けされたディレクトリ内のファイルをマッチ:
SELECT * FROM S3( "uri" = "s3://my-bucket/logs/year=2024/month=*/day=*/data.parquet", "s3.access_key" = "xxx", "s3.secret_key" = "xxx", "s3.region" = "us-east-1", "format" = "parquet" );
:::caution ゼロパディングされたディレクトリ month=01、month=02のようなゼロパディングされたディレクトリ名の場合は、範囲パターンではなくワイルドカード(*)を使用してください。パターン{01..12}は{1,2,...,12}に展開されるため、month=01にマッチしません。 :::
番号付きファイル分割にマッチさせる(例:Spark出力):
SELECT * FROM S3( "uri" = "s3://my-bucket/output/part-{00000..00099}.csv", "s3.access_key" = "xxx", "s3.secret_key" = "xxx", "s3.region" = "us-east-1", "format" = "csv" );
パターンにマッチするすべてのCSVファイルを読み込む:
LOAD LABEL db.label_wildcard ( DATA INFILE("s3://my-bucket/data/file_*.csv") INTO TABLE my_table COLUMNS TERMINATED BY "," FORMAT AS "CSV" (col1, col2, col3) ) WITH S3 ( "provider" = "S3", "AWS_ENDPOINT" = "s3.us-west-2.amazonaws.com", "AWS_ACCESS_KEY" = "xxx", "AWS_SECRET_KEY" = "xxx", "AWS_REGION" = "us-west-2" );
数値範囲展開を使用してファイルを読み込む:
LOAD LABEL db.label_range ( DATA INFILE("s3://my-bucket/exports/data_{1..5}.csv") INTO TABLE my_table COLUMNS TERMINATED BY "," FORMAT AS "CSV" (col1, col2, col3) ) WITH S3 ( "provider" = "S3", "AWS_ENDPOINT" = "s3.us-west-2.amazonaws.com", "AWS_ACCESS_KEY" = "xxx", "AWS_SECRET_KEY" = "xxx", "AWS_REGION" = "us-west-2" );
ワイルドカードを使用してHDFSから読み込み:
LOAD LABEL db.label_hdfs_wildcard ( DATA INFILE("hdfs://namenode:8020/user/data/2024-*/*.csv") INTO TABLE my_table COLUMNS TERMINATED BY "," FORMAT AS "CSV" (col1, col2, col3) ) WITH HDFS ( "fs.defaultFS" = "hdfs://namenode:8020", "hadoop.username" = "user" );
数値範囲でHDFSから読み込み:
LOAD LABEL db.label_hdfs_range ( DATA INFILE("hdfs://namenode:8020/data/file_{1..3,5,7..9}.csv") INTO TABLE my_table COLUMNS TERMINATED BY "," FORMAT AS "CSV" (col1, col2, col3) ) WITH HDFS ( "fs.defaultFS" = "hdfs://namenode:8020", "hadoop.username" = "user" );
ワイルドカードを使用したS3からの挿入:
INSERT INTO my_table (col1, col2, col3) SELECT * FROM S3( "uri" = "s3://my-bucket/data/part-*.parquet", "s3.access_key" = "xxx", "s3.secret_key" = "xxx", "s3.region" = "us-east-1", "format" = "parquet" );
Dorisは、S3/HDFSリスト操作を最適化するために、パスパターンから最長の非ワイルドカードプレフィックスを抽出します。より具体的なプレフィックスを使用することで、ファイル検出が高速化されます。
-- Good: specific prefix reduces listing scope "uri" = "s3://bucket/data/2024/01/15/*.csv" -- Less optimal: broad wildcard at early path segment "uri" = "s3://bucket/data/**/file.csv"
正確なファイル番号がわかっている場合は、ワイルドカードの代わりにレンジパターンを使用してください:
-- Better: explicit range "uri" = "s3://bucket/data/part-{0001..0100}.csv" -- Less optimal: wildcard matches unknown files "uri" = "s3://bucket/data/part-*.csv"
** のような深い再帰的パターンは、大きなバケットでファイルリストの処理が遅くなる原因となります:
-- Avoid when possible "uri" = "s3://bucket/**/*.csv" -- Prefer explicit path structure "uri" = "s3://bucket/data/year=*/month=*/day=*/*.csv"
| 問題 | 原因 | 解決策 |
|---|---|---|
| ファイルが見つからない | パターンがどのファイルにもマッチしない | パスとパターンの構文を確認し、まず単一ファイルでテストする |
| ファイル一覧の処理が遅い | ワイルドカードが広範囲すぎる、またはファイルが多すぎる | より具体的なプレフィックスを使用し、ワイルドカードのスコープを制限する |
| 無効なURI error | パス構文の形式が正しくない | URIスキームとbucket名の形式を確認する |
| Access denied | 認証情報または権限の問題 | S3/HDFS認証情報とbucketポリシーを確認する |
大規模なロードジョブを実行する前に、制限されたクエリでパターンをテストしてください:
-- Test if files exist and match pattern SELECT * FROM S3( "uri" = "s3://bucket/your/pattern/*.csv", ... ) LIMIT 1;
マッチしたファイルのスキーマを検証するには DESC FUNCTION を使用します:
DESC FUNCTION S3( "uri" = "s3://bucket/your/pattern/*.csv", ... );