MongoDB を Rails から使う、導入編

三周遅れくらいの話題ですが、最近お仕事で扱うデータのサイズや件数が増えて来て困る事が多いので今後に備えて。

MongoDB のインストール

Windows でも Mac でもバイナリが配布されているのでダウンロードして解凍するだけで動き Linux の場合も大体のパッケージ管理システムから導入可能です。ただし 32bit 環境はあまり推奨されないようです。

http://www.mongodb.org/downloads

今回は手元の Mac から動かすので、上記ダウンロードページから OS X 64-bit のものをダウンロードし、解凍します。解凍されたディレクトリにはライセンスに関するドキュメントに並んで bin というディレクトリが内包されており、そこに MongoDB のサーバにあたる mongod と、クライアントにあたる mongo のバイナリその他が入っています。

とりあえずコンソールからこの bin ディレクトリに移動して mongod コマンドを入力します。

./mongod

するとおそらくほとんどの環境では次のようなエラーが出力されます。

*********************************************************************
 ERROR: dbpath (/data/db/) does not exist.
 Create this directory or give existing directory in --dbpath.
 See http://dochub.mongodb.org/core/startingandstoppingmongo
*********************************************************************

エラーにも書かれているように MongoDB がデフォルトで用いるデータディレクトリのパスが /data/db になります(Linux 系の OS の場合は /var/lib/mongodb などかもしれません)。もし他のディレクトリを使いたい時は --dbpath で指定しろとの事なので、今回はそちらを採用します。

先ほどの bin ディレクトリに db ディレクトリを作成し、改めてコマンドを入力します。

mkdir db
./mongod --dbpath /path/to/mongodb/bin/db

うまくいくとサーバが立ち上がり、コマンドを待ち受けてくれます。

本格的に MongoDB を使っていくなら bin ディレクトリにパスを通して mongod をサービス登録しておくと便利ですが、今回はとにかく動けばよかろうなので後に回して次に進みます。

Rails アプリケーション側の準備

MongoDB を Rails アプリケーションから使う場合 ActiveRecord は必要ありません。なので、アプリケーション作成時に次のように指定します。

rails new mongo_test --skip-active-record

さらに Gemfile を修正し Ruby から MongoDB 及び MongoDB のデータ管理に使われる BSON を扱えるようにします。

  gem 'rails', '3.X.X'
  gem 'mongo_mapper'
  gem 'bson_ext'

ここまで終わったら bundle install で gem をインストールします。

次に MongoDB 向けの設定ファイルを記述します(今のところ congif/database.yml も MongoDB では使用しません)。config/initializers/mongo.rb というファイルを作成し、次のように編集します。

# coding: utf-8
MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
MongoMapper.database = "#mongo_test-#{Rails.env}"

# 以下は Passenger を絶対に使わないというのであれば不要
if defined?(PhusionPassenger)
  PhusionPassenger.on_event(:starting_worker_process) do |forked|
    MongoMapper.connection.connect if forked
  end
end

MongoMapper.connection がコネクション設定 MongoMapper.database が接続するデータベースの指定になります。何も変更していなければコピー&ペーストで動作すると思います。

Scaffold を通してみる

以上でも MongoDB を使ってアプリケーションを動かす事はできるのですが scaffold すら通らないのでさすがに不便です。そのあたりの橋渡しを行ってくれる mongoid という gem を使って scaffold を通してみます。

まずはいつも通り Gemfile の修正を行います。

  gem 'rails', '3.X.X'
  gem 'mongo_mapper'
  gem 'bson_ext'
  gem 'mongoid'

終わったら bundle install を忘れずに。

次に mongoid の設定ファイルを初期化します。

rails g mongoid:config

ここまでで scaffold が使えるようになったはずです。

rails g scaffold Post title:string subscription:text

完成したクラスを確認してみます。

class Post
  include Mongoid::Document
  field :title, type: String
  field :subscription, type: String
end

ActiveRecord が継承されていない事や text 型がきちんと String として吸収されている事が分かります。MongoDB はスキーマを定義せずに拡張していくので、このままマイグレーションなしで動作させる事が可能です。

なお mongoid の設定ファイルも config/mongoid.yml に作られているので、気になる方は参照してみてください。