いろんなサービスのAPI結果などをキャッシュする的な用途を想定
require 'rubygems' require 'sinatra' require 'json/pure' require 'pstore' require 'active_support' class JsonStore < PStore def initialize(file); super(file); end def dump(table); table.to_json; end def load(content); JSON.load(content); end end db = JsonStore.new('json.dat') helpers do def db_init(db, service, user) db[service] = Hash.new unless db[service] db[service][user] = Hash.new unless db[service][user] db[service][user]["updated_at"] = Time.now.to_i-3600 unless db[service][user]["updated_at"] return db[service][user] end end
/usr/lib/ruby/gems/1.8/gems/solr-ruby-0.0.8/lib/solr/request/standard.rb
を見るといろいろ使い方が書いてある。
ソートの指定はハッシュを配列で渡すと複数のカラムで重み付けできるみたい。
以下は、全エントリから日付降順で最新の30件を取得する例
require 'rubygems' require 'solr' conn = Solr::Connection.new('http://localhost:8180/solr', :autocommit => :on) request = Solr::Request::Standard.new(:query=>'*:*', :rows=>30, :sort=>[{:created_at=>:descending}]) result = conn.send(request) result.each do |i| puts i['title'] puts i['url'] end
検索結果の中のkeyがシンボルになってないのはどうにも一貫性がなく感じる
一般的にはMySQLとかCSVとかからデータを取り込むものらしい
↓のようにsolr-rubyをつかって一件づつドキュメントを追加することも可能
require 'rubygems' require 'digest/md5' require 'solr' value = {:id => Digest::MD5.new.update("http://rubyist.g.hatena.ne.jp/yuiseki/").to_s, :url => "http://rubyist.g.hatena.ne.jp/yuiseki/", :title => "yuisekiのいまさらruby厨日記", :created_at => Time.now} conn = Solr::Connection.new('http://localhost:8180/solr', :autocommit => :on) doc = Solr::Document.new(value) conn.add(doc)
valueの中身はshcema.xmlで指定した型に合わせてそれっぽく。ハッシュ内のkeyはシンボルの形になってなくてはいけない。
KVSのようにkeyは存在しないのでちょっと勝手がちがう感じ。
開くといきなり英語のコメントとかが300行くらい書かれていてぎょっとするが
ポイントとしては、
日本語全文検索を行う場合は、ちょっと複雑なことをしておく必要があるっぽい。
とにかくfieldsを編集してインデックスけして再起動すると、案外素直に動いてくれる。
solrとは
Apache Solrは、OSSの全文検索のエンジンとして有名なApache Luceneをベースに、
HTTPでの入出力(サーバアプリケーション化)
管理Webアプリケーション
キャッシュ機構
などの機能拡張を行ったJavaのWebサーバアプリケーションです。
全文検索サーバ: これからSolrを始める人のためのApache Solr概要と便利な情報リスト集 | イージーネット Tech Blog
debianだとjavaを一度もつかったことがなくても以下のコマンドで環境もふくめて一発でインストールできる
sudo aptitude install solr-tomcat5.5
javaすでに使ってたりtomcatでなんかやってたりした場合はどうなるのか知らない。
インストールするだけで勝手にtomcatが起動して
http://localhost:8180/solr/admin/でsolrが利用可能になっている
ファイアーウォールを使っていなかったり、8180ポートを公開していたりする場合はこの時点でsolr APIを誰でも読み書きできてしまい非常に危険
いろいろいじるまえに、停止する
sudo /etc/init.d/solr stop
最低限、スキーマの設定をいじらないと使い物にならないのでいじる必要がある
インストール直後は勝手にサンプルのスキーマが書かれている
スキーマ設定編集の詳細は次のエントリに書く
sudo vim /etc/solr/conf/schema.xml
schema.xmlを変更したら既存のインデックスを削除する必要がある
sudo rm -r /var/lib/solr/data/index
起動する
sudo /etc/init.d/solr start
rubyで使うためにgemsも入れておく
sudo gem install solr-ruby
config.ru
require 'app' run Sinatra::Application
app.rb
require 'rubygems' require 'sinatra' require 'sinatra/reloader' require 'erb' template :layout do <<EOF <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title><%= @title %></title> <%= @head %> </head> <body> <%= yield %> </body> </html> EOF end helpers do # 適当な便利メソッドを定義する end get '/' do erb %{hello} end
ruby app.rb -p 4567
app.rbをsinatra.rbっていう名前にするとrequire 'sinatra'で自分自身をロードしてしまい `method_missing': undefined methodで起動失敗、はまるので注意
Early2011/05/06 02:14AFAIC that's the best awnser so far!
awrpevysmu2011/05/06 14:21UjYMxN <a href="http://tabgglyfzepa.com/">tabgglyfzepa</a>
klfyvy2011/05/07 22:28rBIBF7 , [url=http://oxiwmglzfcbc.com/]oxiwmglzfcbc[/url], [link=http://bvgbjsgdubyd.com/]bvgbjsgdubyd[/link], http://geloowoucjxc.com/
xrbxwqrkg2011/05/10 00:48laha6h <a href="http://bugltjpergqs.com/">bugltjpergqs</a>
lrpmkafz2011/05/13 12:236Ltkj3 , [url=http://agpdwocwgurw.com/]agpdwocwgurw[/url], [link=http://cazbfvznkbld.com/]cazbfvznkbld[/link], http://cbawpdlnibav.com/
ユーザーごとに中身が別々のzipをダウンロードさせたいんだけど、いちいちzipファイルをディスクに保存したくないような時。
以下の例ではziprubyのZip::Archive.open_bufferメソッドで特定のディレクトリ内のファイルをまとめて圧縮して送信している。
ファイル名とファイル本体のバッファを保持しているハッシュの中身をユーザーごとにカスタマイズすれば、
好きなようにzipの中身をきめて、生成してダウンロードさせることができる。
Zip::Archive.open_bufferはメモリ上のバッファに書き出しが終わるまでレスポンスが送信されないのがちょっと難点で、
巨大すぎるファイルの圧縮だと時間が掛かり過ぎてタイムアウトになってしまうことがあるかもしれない。
メモリではなくTCPsocketにできたところから直接書き出しできれば多少はマシになると思われるので、
超巨大ファイルを圧縮転送したいひとはチャレンジしてやりかた教えてください。
参考までに、総容量100MB~200MB程度だと、ダウンロードして保存するダイアログの表示がちょっともたつく程度でタイムアウトまではしませんでした。
require 'rubygems' require 'sinatra' require 'zipruby' get '/download.zip' do dir = '/home/sinatra/myapp/public/zip' files = [] Dir::foreach(dir) {|f| next if f == "." or f == ".." or f == ".gitignore" files.push dirpath + "/" + f } file_buffers = Hash.new files.each do |path| # fileをbufferにためる filename = File::basename(path) file = open(path, "rb") file_buffers.store filename, file.read file.close # ファイルを閉じる end # オンメモリでzipファイルを生成 zip_buffer = '' Zip::Archive.open_buffer(zip_buffer, Zip::CREATE, Zip::NO_COMPRESSION) do |zipb| # fileのbufferをzipのbufferにつっこんでいく file_buffers.each_pair do |filename, buf| zipb.add_buffer(filename, buf) end end # メモリ上のデータを送信 content_type 'application/zip' attachment 'download.zip' zip_buffer end