LoginSignup
5
3

More than 5 years have passed since last update.

今更ですが、Riakを使ってみる

Last updated at Posted at 2016-09-16

以前試しで Redis を使ってたのですが、メモリ上限が気になって本番環境ではどうだろう、とちょっと躊躇してましたが、「Riakとかどうだろう?」って教えてもらったので、さっそく使ってみました。

インストール

インストールを試みましたが、環境が古くてできませんでした。。。
なので、すでにインストール済みの環境を借りることができたので、それを使います。
# たぶん apt とかでインストールできるかと。。。
# version は 2.0.0 でした。

Rubyから使う

gem install 'riak-client'

でライブラリをインストールします。

っとその前に Riak について

Riak は Erlang で記述された Key-Value Store です。
NoSQLは最近流行ってますね。
データの構造とかは特に考えずに、どかーっとデータを格納して利用したい場面で使います(^^;
あとは色々特徴がありますが、公式を参照してみてください。

基本

Riak は bucket と呼ばれる バケツ にデータを ガーっ と入れます。
バケツ に入れるデータは Key で一意にわかるようなデータで、なんでも入ります。
基本的にはバケツ毎管理なので、バケツが違えば同じ Key でも問題ないみたいです。
ただし、bucket_type というものを使ってくるめることもできるみたいです。

接続

require "riak"

client = Riak::Client.new(:nodes => [{:host => "localhost", :protocol => "pbc", :pb_port => 8087}])

ノードを複数設定することも可能です。

バケツの生成

bucket = client.bucket("users")

users バケツを作りました。
この中に色々入れていきます。
が、このままでは入れて出すだけしかできないので、検索できるように設定します。

検索設定

client.create_search_index("users")
client.set_bucket_props(bucket, { :search_index => "users" })

users に検索インデックスを作成しました。これで検索ができるようになりました。

データ登録

ポイントは、検索対象の項目には _s とか目印をつけなければならないところです。
検索対象が文字列の場合は、 _s (string)
検索対象が数値の場合は、 _i (int)、_l (long)、_d (double)
検索対象がブール値の場合は、 _b (boolean)
などです。

user = bucket.new("Manaka Laala")
user.data = {:birthday_s => "11/20", :bloodtype_s => "O", :favorite_s => "pizza", :charm_s => "lovly", :team_s => "SoLaMiSmile"}
user.store

user = bucket.new("Minami Mirei")
user.data = {:birthday_s => "10/01", :bloodtype_s => "A", :favorite_s => "sweets", :charm_s => "pop", :team_s => "SoLaMiSmile"}
user.store

user = bucket.new("Hojo Sophy")
user.data = {:birthday_s => "07/30", :bloodtype_s => "AB", :favorite_s => "red-flush", :charm_s => "cool", :team_s => "SoLaMiSmile"}

user = bucket.new("Todo Shion")
user.data = {:birthday_s => "01/05", :bloodtype_s => "B", :favorite_s => "daifuku", :charm_s => "cool", :team_s => "DressingPafe"}
user.store

user = bucket.new("Dorothy West")
user.data = {:birthday_s => "02/05", :bloodtype_s => "A", :favorite_s => "monja-yaki", :charm_s => "pop", :team_s => "DressingPafe"}
user.store

user = bucket.new("Reona West")
user.data = {:birthday_s => "02/05", :bloodtype_s => "A", :favorite_s => "strawberry pafe", :charm_s => "pop", :team_s => "DressingPafe"}
user.store

bucket.new の引数が キー になります。これが一意の値でないといけません。
同じ場合は、上書きされるので注意しましょう。
# 実際に使用する場合は、Key は 一意の ID になるのでしょう。

呼び出し、上書き、削除

user = bucket.get("Minami Mirei")

Riak::RObject で帰ってきます。
中身は user.data で見ることができます。
キーが無い場合はエラーになります。

user = bucket.get("Shiratama Mikan")

#> Expected success from Riak but received not_found. The requested object was not found.(Riak::ProtobuffsFailedRequest)

上書きは先ほども触れましたが、同じキーで get して store するだけです。

user = bucket.get("Manaka Laala")
user.data[:favorite_s] = "pizza, da-gashi"
user.store

削除は delete です。キーを指定して削除します。

bucket.delete("Dorothy West")

検索

検索設定をしていれば案外簡単です。

result = client.search("users", "charm_s:cool")

これで charm_s が cool のものを取ってきます。
上の例では Sophy と Shion が返ってきます。
ヒットした数は result["num_found"] に格納されています。
実際の値は result["docs"] に配列として格納されていますので、取り出して利用します。

p result["num_found"]
#> 2

p result["docs"]
#> [{"score"=>"1.83000e+00", "_yz_rb"=>"users", "_yz_rt"=>"default", "_yz_rk"=>"Hojo Sophy", "_yz_id"=>"1*default*users*Hojo Sophy*6", "birthday_s"=>"07/30", "bloodtype_s"=>"AB", "favorite_s"=>"red-flush", "charm_s"=>"cool", "team_s"=>"SoLaMiSmile"}, {...}]

が、戻りは普通のハッシュデータなので、キーを取得して、バケツから取り出した方が素直かもしれません。
キーは _yz_rk で、バケツは _yz_rb です。

result["docs"].each do |doc|
  key = doc["_yz_rk"]
  user = bucket.get(key)
  ...
end

検索文字列

上記の例では charm_s:cool がこれに該当します。
これは、 charm_s が cool のもの で SQL文では charm_s = 'cool' にあたります。
同様に、

charm_s like '%c%' は charm_s:*c* になります。
charm_s = 'pop' and team_s like '%So%' の場合は charm_s:pop AND team_s:*So* になります。

AND は大文字でないと認識しないので注意しましょう。
数値の場合は

age = 10 は age_i:10
age > 10 and age =< 15 は age_i:[11 TO 15]

です。

とりあえず、以上な感じですかね。
普通に使う感じではこれくらいあればいけるかなと思います。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3