LoginSignup
5
5

More than 5 years have passed since last update.

rubyでMongoDBクエリしてみた(mongoid)

Posted at

ケース

  • コレクション名は、access_log
  • apacheのログをLTSV形式で収集している
    • http://ltsv.org/
    • LogFormat "host:%h\tident:%l\tuser:%u\ttime:%t\treq:%r\tstatus:%>s\tsize:%b\treferer:\%{Referer}i\tua:%{User-Agent}i" combined_ltsv

準備

Configuration

http://mongoid.org/en/mongoid/docs/installation.html#configuration
省略

Document定義

class AccessLog
  include Mongoid::Document
  store_in collection: "access_log"
end
AccessLog.last.as_document
=> {"_id"=>"5338b6e0058281474986c8a6",
 "host"=>"10.0.0.1",
 "ident"=>"-",
 "user"=>"-",
 "time"=>2014-01-01 00:00:00 UTC,
 "req"=>"\"GET / HTTP/1.1\"",
 "status"=>"200",
 "size"=>"1024",
 "referer"=>"-",
 "ua"=> "\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:27.0) Gecko/20100101 Firefox/27.0\""}

 クエリ

http://mongoid.org/en/mongoid/docs/querying.html
ActiveRecordライクな(?)DSLが定義してあるので、あとは慣れの問題か。

MyDSLを定義しておくと、少しは便利かな。

module DSL
  def time(times)
    where({time: times})
  end

  def status(code)
    where(to_status_hash(code))
  end
  alias :status_and :status

  def status_or(*codes)
    self.or(codes.map{|code| to_status_hash(code)})
  end

  def status_not(code)
    self.not(to_status_hash(code))
  end

  private
  def to_status_hash(code)
    {status: code.is_a?(Regexp) ? code : Regexp.new(code.to_s)}
  end
end

module Mongoid
  class Criteria
    include DSL
  end
end

class AccessLog
  include DSL
end

以下、どれも同じselectorとなる。

AccessLog.where(time: 1.days.ago..Time.now).where(status: /5\d\d/)
=> #<Mongoid::Criteria
  selector: {"time"=>{"$gte"=>2014-01-01 00:00:00 UTC, "$lte"=>2014-01-01 10:00:00 UTC}, "status"=>/5\d\d/}
  options:  {}
  class:    AccessLog
  embedded: false>

AccessLog.where(time: 1.days.ago..Time.now, status: /5\d\d/)
=> #<Mongoid::Criteria
  selector: {"time"=>{"$gte"=>2014-01-01 00:00:00 UTC, "$lte"=>2014-01-01 10:00:00 UTC}, "status"=>/5\d\d/}
  options:  {}
  class:    AccessLog
  embedded: false>

AccessLog.time(1.days.ago..Time.now).status(/5\d\d/)
=> #<Mongoid::Criteria
  selector: {"time"=>{"$gte"=>2014-01-01 00:00:00 UTC, "$lte"=>2014-01-01 10:00:00 UTC}, "status"=>/5\d\d/}
  options:  {}
  class:    AccessLog
  embedded: false>
5
5
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
5