U-SQL 入門④ ~ FileSets ~

FileSets を使って複数のファイルを EXTRACT 文で読み込むことができます。

基本

以下のように 5 ファイルがある場合、

/input/2018-01-01.log
/input/2018-02-01.log
/input/2018-03-01.log
/input/2018-04-01.log
/input/2018-05-01.log

以下の EXTRACT 文で 5 ファイルをすべて読み込むことができます。また、{suffix} にマッチした部分を suffix 列に入れることができます。

@rs =
	EXTRACT
		user string,
		id string,
		suffix string
	FROM "/input/{suffix}.log"
	USING Extractors.Csv();

日付形式の対応

以下のように 5 ファイルがある場合、

/input/2018-01-01.log
/input/2018-02-01.log
/input/2018-03-01.log
/input/2018-04-01.log
/input/2018-05-01.log

以下の EXTRACT 文ではファイル名の日付情報を、DateTime 型の値として取得することができます。

@rs =
	EXTRACT
		user string,
		id string,
		date DateTime
	FROM "/input/{date:yyyy}-{date:MM}-{date:dd}.log"
	USING Extractors.Csv();

以下のようなフォルダ構成になっている場合、

/input/2017/01/01/data.txt
/input/2017/02/01/data.txt
/input/2017/03/01/data.txt
/input/2017/04/01/data.txt
/input/2017/05/01/data.txt

以下の EXTRACT 文でフォルダ構造から日付情報を、DateTime 型の値として取得することができます。

@rs =
	EXTRACT
		user string,
		id string,
		date DateTime
	FROM "/input/{date:yyyy}/{date:MM}/{date:dd}/data.txt"
	USING Extractors.Csv();

このデータに SELECT を実行する際に以下のように WHERE 句で DateTime 型の範囲でフィルターをかけることができます。

@rs =
	SELECT * FROM @rs
	WHERE 
		date >= System.DateTime.Parse("2018/1/1") AND
		date < System.DateTime.Parse("2018/2/28");

フィルターの効能

以下のようなファイルを読み込むとき、

/input/ja_data-01.log
/input/ja_data-02.log
/input/en_data-01.log
/input/en_data-02.log
/input/cn_data-01.log

以下の EXTRACT 文でファイル名の先頭にある文字列を {Market} に格納できます。

@rs =
	EXTRACT
		user string,
		id string,
		Market string
	FROM "/input/{Market}_{*}"
	USING Extractors.Csv();

SELECT 文を実行する際に以下のように Market 列でフィルターをかけると、/input/ja_data-01.log、/input/ja_data-02.log の 2 つのファイルのみが読み取られ、その他のファイルにはアクセスされないため、I/O 効率が良くなります。

@us =
	SELECT * FROM @rs
	WHERE Market == “ja" ;