Edited at

DynamoDBのテーブルからnode.jsでランダムにItemを取ってくる


DynamoDBのテーブルからランダムにItemを取ってくる方法

たとえば総数10個のレコードある以下のようなsampleテーブルからランダムに1件取ってくる場合、

sampleテーブル:

HAIKU_table.png

RDBならSQL文1行で済みますね。

select HAIKU from sample order by rand() limit 1

これを使ってNode.jsでコード書くと、

// 接続詞は省略

connection.query('select HAIKU from sample order by rand() limit 1', function(err, rows) {
if(err) {
return console.log(err)
}else{
HAIKU = rows[0].HAIKU
console.log(HAIKU)
}
});

ああ簡単:expressionless:


じゃあ、NoSQLのDyanamoDBではどうしましょ・・・

意外とムツカシイ方法でみなさん苦戦しているようなのでこれでいいんじゃないの、という方法を載せておきます。

var AWS = require('aws-sdk');

var docClient = new AWS.DynamoDB.DocumentClient();
var util = require('util');

// DynamoDBのsampleテーブルをScanしItem総数を獲得
var params = {
TableName: 'sample',
Select: "COUNT" // Selectはアイテム総数を返すパラメーター
};

docClient.scan(params, function(err, data){
if(err){
console.log(err);
}else{
util.inspect(data,false,null);
var length = data["Count"];  //data["Count"]に全Item数が入ります
randomNum = Math.floor(Math.random() * length);
console.log('randomNumは ' + randomNum);
callHAIKU(randomNum);
}
});

// ランダム整数randomNumを引数にsampleテーブルからランダムにHAIKU文字列を獲得
function callHAIKU(arg){
var randomNum = arg;
var params = {
TableName: 'sample',
Key: { // SQLのwhere条件文にあたるパラメーター
'ID': randomNum
}
};
docClient.get(params, function(err,data) {
if(err){
console.log(err);
}else{
var result = JSON.stringify(data.Item)
//data.ItemはJSON文字列の{"ID":3,"HAIKU":"春雨や食はれ残りの鴨が鳴く"}
var result = JSON.parse(result.HAIKU);
//parseしてresultをオブジェクト化する
}
})
}

Scanで総件数をまず取ってきて、それをvar lengthに格納。

それを使って

randomNum = Math.floor(Math.random() * length)

の式で1〜10までのランダムな整数をrandomNum変数に格納。

randomNum変数を引数にしてcallHAIKU()関数の中でHAIKU文字列を取ってきます。

最終的にresult変数に俳句の部分だけ、たとえば"春雨や食はれ残りの鴨が鳴く"が格納されます。


この文字列をランダムにツイートしたりラインで毎朝一斉メッセージしたりするって使い方。


ただ、

DynamoDBでは一度のScanに1MBの制限があるので注意。テーブルのサイズが大きいと全件数が取ってこれません。

ただ上記のような簡素なテーブルで10レコードなら3KBもないのでその300倍くらいのサイズまで大丈夫。(3,000レコードとか)

それにさ、1MB制限もそのうち1GB制限とかに増えていくんじゃない?:sunny: