S3でSQL文が使えるんですね。知らなかったです。
さっそく使ってみました。
入力となるJSONファイルはS3上にこんな感じである前提です。
{
"info": "This is sample",
"data_list": [
{
"x": 1,
"value": 11,
"comment": "comment 1-1"
},
{
"x": 1,
"value": 12,
"comment": "comment 1-2"
},
{
"x": 2,
"value": "21",
"comment": "comment 2-1"
},
{
"x": 2,
"value": 22,
"comment": "comment 2-2"
}
]
}
そして、コードです。
var AWS = require('aws-sdk');
AWS.config.update({
region: "ap-northeast-1",
});
var s3 = new AWS.S3({
});
const S3SELECT_DELIMITER = '\n';
const sql = 'SELECT * FROM s3object[*].data_list[*] AS s';
const params = {
Bucket: 'bucket-test',
Key: 'test/data.json',
ExpressionType: 'SQL',
Expression: sql,
InputSerialization: {
JSON: {
Type: "DOCUMENT"
}
},
OutputSerialization: {
JSON: {
RecordDelimiter: S3SELECT_DELIMITER
}
}
};
var result = await s3.selectObjectContent(params).promise();
console.log(result);
const events = result.Payload;
let list = [];
for await (const chunk of events) {
if( chunk.Records){
var t1 = chunk.Records.Payload;
var t2 = t1.toString();
var t3 = t2.split(S3SELECT_DELIMITER);
for( const item of t3){
if( item )
list.push(JSON.parse(item));
}
}
}
console.log(JSON.stringify(list, null, '\t'));
結果は以下のように出力されます。
[
{
"x": 1,
"value": 11,
"comment": "comment 1-1"
},
{
"x": 1,
"value": 12,
"comment": "comment 1-2"
},
{
"x": 2,
"value": "21",
"comment": "comment 2-1"
},
{
"x": 2,
"value": 22,
"comment": "comment 2-2"
}
]
後処理の部分がわかりにくいかもしれませんが、result.Payloadは、Readable Streamです。
以下の部分がSQL文に相当します。JSONの中のdata_listをSQLの対象にしています。
const sql = 'SELECT * FROM s3object[*].data_list[*] AS s';
また、一番やりたかった出力をフィルタリングしたい場合は、例えば以下のように書き換えると
const sql = 'SELECT s.x, s.value FROM s3object[*].data_list[*] AS s WHERE s.x = 1';
以下のような出力となります。
[
{
"x": 1,
"value": 11
},
{
"x": 1,
"value": 12
}
]
ちなみに、今回は入力ファイルがJSONの場合でしたが、もしJSON Linesの場合は、以下の部分を
JSON: {
Type: "DOCUMENT"
}
以下のように変えます。
JSON: {
Type: "LINES"
}
入力ファイルとしてCSVの場合が多いかもしれませんが、詳細は以下ご参照ください。
(参考)
https://aws.amazon.com/jp/blogs/developer/introducing-support-for-amazon-s3-select-in-the-aws-sdk-for-javascript/
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#selectObjectContent-property
ちなみに、ちゃんとMINIOでも動いてくれますよっ
おわりに
うーん、ルートが配列のJsonファイルはダメっぽいなあ
以上