みなさんこんにちは。最近はAzureにどっぷりです。
今日は、AzureのNoSQLデータベースサービスである、DocumentDBを、node.jsから使ってみたいと思います。
DocumentDBとは?
DocumentDBは、ドキュメント型NoSQLに区分される、jsonドキュメントを格納するためのデータベースです。
同じドキュメント型のNoSQLとしては、 AWS DynamoDBが挙げられます。
DocumentDBは、NoSQL(Not only sql)ですが、SQLが使えます。
NoSQLの詳しい説明については、既に色々な記事で書かれていますので、ここでは割愛します。
Azure DocumentDB vs AWS DynamoDB
DocumentDBは、SQLでドキュメントをクエリ出来て、何の設定もしなくてもドキュメントがソートできてしまいます。
DynamoDBで同じことをやろうとすると、DynamoDB独特の書き方を学習したり、レンジキーを設定したりと、色々やらなければいけないことがあるのですが、DocumentDBでは、慣れ親しんだSQLをほぼそのまま書くことで対応できてしまいます。
これは衝撃的でした。
コードで比較してみましょう。
まずはAWS DynamoDBから。
DynamoDBにおけるドキュメント取得とフィルタリング
var AWS = require("aws-sdk");
var docClient = new AWS.DynamoDB.DocumentClient();
var params = {
TableName: "FileUploadLog",
ProjectionExpression: "#ts, Filename",
FilterExpression: "#ts between : start_date and : end_date",
ExpressionAttributeNames: {
"#ts": "TimeStamp",
},
ExpressionAttributeValues: {
":start_date": "2016-10-10 00:00:00",
":end_date": "2016-10-15 00:00:00"
}
};
docClient.scan(params, onScan);
function onScan(err, data) {
if (err) {
console.error("Unable to scan the table. Error JSON:", JSON.stringify(err, null, 2));
} else {
// print all the movies
console.log("Scan succeeded.");
data.Items.forEach(function(log) {
console.log(JSON.stringify(log));
});
// continue scanning if we have more movies
if (typeof data.LastEvaluatedKey != "undefined") {
console.log("Scanning for more...");
params.ExclusiveStartKey = data.LastEvaluatedKey;
docClient.scan(params, onScan);
}
}
}
docClient.scanの結果がコールバックに返され、次のデータ取得用のキー(LastEvaluatedKey)が入っていたら、それをExclusiveStartKeyに指定して、またscanを実行する、という方法です。
時刻などでアイテムをフィルタリングする場合は、FilterExpressionに条件を指定します。
では次にDocumentDBの方を見ていきましょう。
DocumentDBにおけるドキュメント取得とフィルタリング
var TaskDao = require("./taskDao"); //DocumentDB wrapper
var config = {};
config.host = "YOUR_DOCUMENTDB_HOST_ADDRESS";
config.authKey = "YOUR_AUTH_KEY";
config.databaseId = "YOUR_DATABASE_ID";
config.collectionId = "YOUR_COLLECTION_ID";
var DocumentDBClient = require("documentdb").DocumentClient;
var docDbClient = new DocumentDBClient(config.host, {
masterKey: config.authKey
});
var taskDao = new TaskDao(docDbClient, config.databaseId, config.collectionId);
new Promise((resolve, reject) => {
taskDao.init((err) => {
if (err) {
reject(err);
return;
}
resolve();
});
})
.then((data) => {
console.log("data: ");
console.log(JSON.stringify(data));
return new Promise((resolve, reject) => {
var querySpec = {
query: "SELECT TOP @limit * FROM root r WHERE r.TimeStamp BETWEEN @start_date AND @end_date",
parameters: [{
name: "@limit",
value: 10
},{
name: "@start_date",
value: "2016-10-15 00:00:00"
},{
name: "@end_date",
value: "2016-10-20 00:00:00"
}]
};
taskDao.find(querySpec, function (err, items) {
if (err) {
reject(err);
return;
}
resolve(items);
});
});
})
.then((data) => {
console.log("data :");
console.log(JSON.stringify(data));
})
.catch((err) => {
console.log("err :");
console.log(JSON.stringify(err));
});
なんと普通にSELECT *
できてしまいます。これは非常に簡単ですね。
ソートも簡単です。最新10件取得ならこんなクエリを発行すれば良いです。
SELECT TOP 10 * FROM root r ORDER BY r.TimeStamp DESC
DocumentDBではORDER BY
句で普通にソート出来てしまいました。
DocumentDBのこの柔軟さはかなり使い勝手の面でアドバンテージが大きいと思います。成果物の完成スピードが段違いに早くなりますね。
まとめ
今日はDocumentDBをNode.jsから使ってみました。
AWS DynamoDBと比較すると、使い勝手の面でかなりの差があることがわかります。
もちろん、性能・価格・柔軟性、色々なファクターがありますので、1軸で評価し甲乙を付けることは出来ませんが、SQLで簡単にデータ検索、フィルタリング、ソートが出来てしまうのは、かなり魅力的なんではないでしょうか。
Azureのサービスの中でもとりわけお勧めしたいサービスです。
参考記事
実装に際して、下記の記事を参考にさせていただきました。
Node.js ExpressからDocumentDBを扱う方法が、サンプルコードと共に示されているので、とても分かりやすいです。
本記事中で使用している、DocumentDBのラッパーtaskDao
の実装も載っています。
https://docs.microsoft.com/ja-jp/azure/documentdb/documentdb-nodejs-application