CakePHPからMongoDBを使うための導入手順とクエリの注意点
はじめに
柔軟なスキーマやスケーラビリティから、多くのプロジェクトで採用されるようになったNoSQLデータベース「MongoDB」。
これを、MySQLのようなリレーショナルデータベース(RDB)を前提として設計されているCakePHPのようなフレームワークと、どう連携させれば良いのでしょうか?
この記事では、自身のWikiに書き溜めていたメモを元に、CakePHPからMongoDBを扱うための基本的な導入手順と、特にRDBの常識で考えるとハマってしまうクエリの注意点を共有します。
Step 1: MongoDBとPHP拡張のインストール
まず、サーバーにMongoDB本体と、PHPからMongoDBを操作するためのPHP拡張機能をインストールします。
MongoDBのインストール (CentOS/RHEL系)
公式のyumリポジトリを追加してインストールするのが簡単です。
# /etc/yum.repos.d/mongodb-org-4.4.repo などのファイルを作成
[mongodb-org-4.4]
name=MongoDB Repository
baseurl=[https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.4/x86_64/](https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.4/x86_64/)
gpgcheck=1
enabled=1
gpgkey=[https://www.mongodb.org/static/pgp/server-4.4.asc](https://www.mongodb.org/static/pgp/server-4.4.asc)
sudo yum install -y mongodb-org
sudo service mongod start
sudo chkconfig mongod on
PHP用MongoDB拡張のインストール
pecl
コマンドでPHP用のドライバをインストールします。
sudo pecl install mongodb
注意:
mongo
という名前の古いPECLパッケージもありますが、現在は非推奨です。新しいmongodb
パッケージを使いましょう。
インストール後、php.ini
に拡張機能を追加するのを忘れないようにします。
extension=mongodb.so
最後にApacheやphp-fpmを再起動すれば、PHPからMongoDBを扱えるようになります。
Step 2: CakePHP用Pluginの導入と設定
次に、CakePHPのDataSourceとしてMongoDBを扱えるようにするためのプラグインを導入します。今回は、広く使われているichikaway/cakephp-mongodb
を例にします。
- プラグインを
app/Plugin/
ディレクトリに設置します。 -
app/Config/bootstrap.php
でプラグインを読み込みます。CakePlugin::load('Mongodb');
-
app/Config/database.php
にMongoDB用の接続設定を追加します。public $mongodb = array( 'datasource' => 'Mongodb.MongodbSource', 'host' => 'localhost', 'database' => 'your_db_name', 'port' => 27017, 'prefix' => '', 'persistent' => 'true', );
モデルでpublic $useDbConfig = 'mongodb';
と指定すれば、そのモデルはMongoDBに接続されるようになります。
最重要ポイント:SQL脳からの切り替え
ここまでの設定で、ほぼMySQLと同様のfind()
メソッドなどが使えます。しかし、いくつかMongoDB特有の「お作法」があり、これを知らないとクエリが全く意図通りに動作しません。
比較:MySQL (SQL) vs MongoDB (NoSQL)
foreign_key_id
が1
で、かつ色がred
またはblue
のデータを取得する、というよくあるfind('all')
の例です。
▼ MySQLの場合
$foreignKeyId = 1; // integer
$options = array(
'conditions' => array(
'Test.foreign_key_id' => $foreignKeyId,
'OR' => array(
array('Test.color' => 'red'),
array('Test.color' => 'blue'),
)
),
);
$tests = $this->Test->find('all', $options);
▼ MongoDBの場合
$foreignKeyId = 1;
$options = array(
'conditions' => array(
'Test.foreign_key_id' => (string)$foreignKeyId, // ★注意点1
'$or' => array( // ★注意点2
array('Test.color' => 'red'),
array('Test.color' => 'blue'),
)
),
);
$tests = $this->Test->find('all', $options);
注意点1:数値型のIDは文字列にキャストする
MongoDBの_id
は通常ObjectIdですが、RDBのINT
型のように扱っていた自前のID(foreign_key_id
など)を検索条件に使う場合、数値のままだとヒットしません。明示的に文字列にキャストする必要がありました。
注意点2:OR
は$or
になる
CakePHPのOR
やAND
といったキーは、MongoDB用のDataSource内では$or
や$and
といったMongoDBネイティブの演算子に変換されます。
おわりに
CakePHPからMongoDBを扱うのは、プラグインのおかげで非常に簡単です。しかし、実際にクエリを書き始めると、RDBの常識が通用しない場面でつまづくことがあります。
特に、データ型の違いとクエリ演算子の記法は、最初に押さえておくべき重要なポイントです。このメモが、これからCakePHPとMongoDBの連携に挑戦する方の助けになれば幸いです。
この記事で紹介した内容以外にも、技術情報をブログで発信しています。
MyNote by MEANTIX
Discussion