Dynamosaurusは、rubyでAmazon DynamoDBを操作するOR Mapperです。使い方は簡単です。dynamosaurusのgemをinstallします。
gem install dynamosaurus
bundleを使っている場合には、Gemfileに追加して
bundle install
続いてmodelを定義します。
require "dynamosaurus"
Aws.config = {
:endpoint => "http://localhost:8000",
:region => 'local_test',
}
class SimpleKVS < Dynamosaurus::DynamoBase
key :simple_key, :string
end
class SimpleOrderedKVS < Dynamosaurus::DynamoBase
key :simple_key, :string, :simple_id, :string
secondary_index :updated_at_index, :updated_at, :number
end
class Comment < Dynamosaurus::DynamoBase
key :content_id, :string, :message_id, :string
global_index :user_index, :user_id, :string
end
dynamosaurusはaws-sdkのv2を使っていてawsの設定はaws-sdkの設定をみます。上記では、ローカルで動いているdynamodb_localを使うように設定しています。
modelのクラスにはkeyとindexを定義しています。
keyは、key名と型を書きます。1つ目はHASHキー、2つ目はRANGEキーです。
indexは、global_indexとsecondary_indexが定義できます。keyと違う点は1つ目にkey nameを指定します。global_indexはkeyと同じ内容、secondary_indexはRANGEキーのみが定義できます。
Dynamosaurus::DynamoBase.create_tables
で、テーブルが作成されます。作成されるテーブル名は#{table_name}_localと自動的に決定されます。今回のモデルでは、comment_local, simpleorderedkvs_localの2つのテーブルが作成されます。ENV['DYNAMODB_SUFFIX']で"_production", "_development"など指定して、テーブル名のsuffixを変更できます。
SimpleKVSで、CRUDとadd(加算)をします。
SimpleKVS.put({:simple_key => "key", :num => 1})
SimpleKVS.get("key").num # => 1
SimpleKVS.first.num # => 1
SimpleKVS.add("key", {:num => 1})
SimpleKVS.first.num # => 2
kvs = SimpleKVS.first
kvs.update({:opt => "1"})
kvs.opt # => 1
kvs.attr_delete(["opt"])
kvs.try(:opt) # => nil
kvs.delete
SimpleKVS.get("key") # => nil
secondary indexを使う場合は
SimpleOrderedKVS.put({:simple_key => "key", :simple_id => "1"})
sleep 1
SimpleOrderedKVS.put({:simple_key => "key", :simple_id => "3"})
sleep 1
SimpleOrderedKVS.put({:simple_key => "key", :simple_id => "2"})
SimpleOrderedKVS.get(
{:simple_key => "key"},
{:scan_index_forward => false, :limit => 50}).
map{|kvs| kvs.simple_id }
# => [2, 3, 1]
dynamosaurusでは更新時に updated_at にtimestampをつけて保存しています。上記例ではupdated_atの時刻をずらすためにsleep 1をしています。これで作成したデータを更新順に取得しています。secondary indexはmodelで定義しているので、データ取得時にはindexを明示的に指定する必要がありません。
また、keyがHASHキーとRANGEキーのmodelはデータをgetするときにkeyを配列で指定します。
SimpleOrderedKVS.get(["key", "1"]).simple_id # => "1"
global indexを使う場合も同様です。
Comment.put({:content_id => "1", :message_id => "1", :user_id => "abc"})
Comment.put({:content_id => "1", :message_id => "2", :user_id => "abc"})
Comment.put({:content_id => "1", :message_id => "3", :user_id => "xyz"})
Comment.get(
{:user_id => "abc"}
).map{|comment| comment.message_id}
# => ["2", "1"]
このようにdynamosaurusを使うとjsonのスキームと格闘してテーブルを作成する必要がなくなり、またindexを使ったデータ取得が簡単に行うことができます。