Ruby(または Ruby on Rails)から、リモート(HTTP)接続で Groonga を利用する
前回の記事:CentOS 6.4(仮想環境)にMySQL 5.5 と Groonga 4.0 を環境構築、Web アプリケーションから接続する。
今回の記事では、Ruby(または Ruby on Rails)から、リモート接続先の Groonga を利用する方法を紹介します。
上記「前回の記事」の内容が、前提となる構成ですので、よろしければこちらもご参照ください。
既存のソリューションについて
※ 2014/09/30 この項の内容について、コメント欄にてご指摘を頂きました。
それの内容を元に、一部訂正をしております。
Groonga を Ruby から利用するためのソリューションを提供しているプロジェクトとして、
「ラングバプロジェクト」というものがあります。
この中に、今回使えるものがないか? 少し調べてみました。
「Rroonga(るるんが)」
これは「Groongaの機能をRubyから利用するためのライブラリ」という風に解説されています。
ただ、少し使ってみたところ、リモート(HTTP)接続することはできないのかな?という感じでした。
後ほど、コメント欄にて「kou 様」に下記のようにご指摘いただきました。
RroongaはローカルのGroongaデータベースを直接操作するライブラリーなので
リモートのGroongaoサーバーに接続する機能はありません!
なるほど。。
というわけで、リモート接続したいという意味ではちょっと使うことができなさそうです。
「ActiveRroonga」
もうひとつのこっちはどうかな?ということで少し調べてみました。
「ActiveRroonga」に関しても「kou 様」にご指摘いただいた内容がわかりやすかったので、
失礼ながらこちらも転載させていただきます <(_ _)>
ActiveGroongaはRroongaをRailsで使いやすくするラッパーです。
多くのことはRroongaでやっているのでActiveGroongaはあんまりやることはありません。
Railsがバージョンアップしたときに動かなくなったら対応するくらいです。なので、あんまり更新がありません。
ActiveGroongaはRroongaのラッパーなのでやはりローカルのGroongaデータベースを操作するためのものです。
リモートのGroongaサーバーにアクセスするためのものではありません。
ありがとうございます m(_ _)m
「groonga-client gem」
こちらも教えていただいたものですが、こちらの gem はリモート接続に対応しています。
Groonga-client is a client for groonga (http://groonga.org/) implemented with pure ruby.
Groonga-client gem supports HTTP or GQTP (Groonga Query Transfer Protocol) as the protocol using a client. You can use it without groonga package.
Groonga をリモート接続(HTTP)で使う処理を、自分で書くことにした
結局、自分で書くことにしました。(そんなに大した処理でもなさそうだったので)
大雑把に、次のようなコードです。
(ruby 2.0 系で動作確認済み)
groonga_connection.rb
require "yaml" require "json" require "net/http" # Groonga へのアクセスを提供するクラス class GroongaConnection FILEPATH = "config/groonga.yml" # 初期化 def initialize # 設定ファイルの内容 @config = nil if File.exist?(FILEPATH) open(FILEPATH) do |f| str = f.read @config = YAML.load(str) @config.freeze end end end # コマンド実行 def command(command_str, params = {}, post_body = nil) # 環境を決定 config = @config["development"] # GET or POST? if post_body.nil? # 結果を取得 response = Net::HTTP.get(config["host"], "/d/" + command_str + build_url_params(params), config["port"]) @latest_response = JSON.parse(response) else uri = URI("http://" + config["host"] + ":" + config["port"].to_s + "/d/" + command_str + build_url_params(params)) request = Net::HTTP::Post.new(uri) request.body = post_body request.content_type = "application/json" response = Net::HTTP.start(uri.hostname, uri.port) do |http| http.request(request) end @latest_response = response.body end end # ハッシュ値からURLパラメータを組み立てる def build_url_params(params) ret = "" # params が存在している場合は、URLパラメータを組み立てる unless params.empty? ret = "?" params.each do |key, value| ret += key.to_s + "=" + value.to_s + "&" end ret.chop! end ret end # 最後に実行したコマンドの結果を返す def latest_response @latest_response end end
config/groonga.yml
このファイルにはリモート接続情報を記述します
# Groonga 環境設定 development: host: 192.168.1.1 # 任意の接続先 port: 10041 # 任意のポート
GroongaConnection クラスの使い方
Groonga の status を実行してみます。
# インスタンス生成 groonga = GroongaConnection.new # "status" 実行 groonga.command("status") # => [[0,1411798109.95856,0.000993490219116211],{"alloc_count":162,"starttime":1411798083,"uptime":26,"version":"4.0.5","n_queries":0,"cache_hit_rate":0.0,"command_version":1,"default_command_version":1,"max_command_version":2}]
select コマンドはこんな感じ
groonga = GroongaConnection.new groonga.command("select", {:table => "Articles"})
load は、ユーザー入力された非常に大きなデータが渡される可能性があるので、GET リクエストではなく POST リクエストで渡します。第3引数は、POST の content body として使われます。
groonga = GroongaConnection.new groonga.command("load", {:table => "Articles"}, '[{"_key": 1, "title": "hoge", "body": "piyo"}]')
あとは、いろいろアレンジ・改良してお試しくださいませ。