🍃

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に拡張機能を追加するのを忘れないようにします。

php.ini
extension=mongodb.so

最後にApacheやphp-fpmを再起動すれば、PHPからMongoDBを扱えるようになります。

Step 2: CakePHP用Pluginの導入と設定

次に、CakePHPのDataSourceとしてMongoDBを扱えるようにするためのプラグインを導入します。今回は、広く使われているichikaway/cakephp-mongodbを例にします。

GitHub - ichikaway/cakephp-mongodb

  1. プラグインをapp/Plugin/ディレクトリに設置します。
  2. app/Config/bootstrap.phpでプラグインを読み込みます。
    CakePlugin::load('Mongodb');
    
  3. 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_id1で、かつ色が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のORANDといったキーは、MongoDB用のDataSource内では$or$andといったMongoDBネイティブの演算子に変換されます。

おわりに

CakePHPからMongoDBを扱うのは、プラグインのおかげで非常に簡単です。しかし、実際にクエリを書き始めると、RDBの常識が通用しない場面でつまづくことがあります。

特に、データ型の違いとクエリ演算子の記法は、最初に押さえておくべき重要なポイントです。このメモが、これからCakePHPとMongoDBの連携に挑戦する方の助けになれば幸いです。


この記事で紹介した内容以外にも、技術情報をブログで発信しています。
MyNote by MEANTIX
https://meantix.com/

Discussion