nazolabo

フリーランスのWebエンジニアが近況や思ったことを発信しています。

PHPでMongoDBを使ってみる

5ヶ月ぶりの更新とかどういうことなの…

MongoDBのインストール

バイナリが配布されているのでそれを使う
http://www.mongodb.org/
自分のプラットフォーム用バイナリを落として、/opt/mongoに入れると仮定。変なプラットフォームの人はgithubから拾ってくる。
あとデータフォルダがデフォルトで/data/dbとかという変なパスなので作る

sudo mkdir -p /data/db

PHP拡張を入れる

sudo pecl install mongo

あとphp.iniにextension=mongo.soを書く

起動

普通に実行してもいいけど
http://gist.github.com/232227
このへんにinitスクリプトがあるので拾ってきてパスを書き換える

使い方

ここから本編
というかチュートリアルがあるからそれを参考にする
http://www.mongodb.org/display/DOCS/PHP+Tutorial

DBに接続
$mongo = new Mongo();

外部に接続する場合は

$mongo = new Mongo("example.com:65432");
データベースを取得

RDBのデータベースと同じ単位だと思われるデータベースへの接続ハンドラ(?)を取得

$db = $mongo->selectDB( "dbname" );

あ、CREATE DATABASE的なものはいらないです。

コレクションを取得

RDBのテーブルと同じ単位だと思われるコレクションへの接続ハンドラ(?)を取得
ハンドラというか何て呼ぶんだこれは

$col = $db->selectCollection( "collectionname" );

あ、CREATE TABLE的なものはいらないです。

コレクションにデータを入れる

いわゆるINSERT
テーブル定義なんてものはないよ!自由に入れれるよ!

$doc = array( "name" => "MongoDB",
   "type" => "database",
   "count" => 1,
   "info" => (object)array( "x" => 203,
       "y" => 102),
   "versions" => array("0.9.7", "0.9.8", "0.9.9")
);
$col->insert( $doc );

こんな感じで、自由に定義した配列を入れれる。勝手に拡張もできる。
ちなみにinsertすると、内部ID保持用に_idというキーが自動的に$docに入る。あとでUPDATEとかに使う。

1項目取得

findOneというそのままな

$obj = $col->findOne();
var_dump( $obj );

条件指定する場合は

$obj = $col->findOne(array("name"=>"MongoDB"));
var_dump( $obj );

ない場合はnullを返す

件数取得
$col->count();
複数項目取得

findでできる

$cursor = $col->find();
foreach ($cursor as $id =>$obj) {
  var_dump( $obj );
}

findが返すのはカーソルなので、foreachで回して処理する。もちろんfindに条件を指定することもできる。
ちなみに

$cursor->count();

で、問い合わせ結果の件数を取得できる。
ORDER BY的なことをしたい場合は、

$cursor->sort(array('name'=>1));

とかする。-1にすると逆順になる。この「1で昇順、-1で降順」は他でも出てくる。

インデックスの作成
$col->ensureIndex( array( "name" => 1 ) );

というわけで出てきました。
複合インデックスの場合は

$col->ensureIndex( array( "name" => 1 , "count" => -1 ) );

みたいに。
第二引数をTRUEにするとunique制約になる。

データの更新
$col->update(array("name" => "MongoDB"), $newobj);

第三引数にTRUEを指定すると、対象が見つからない場合にINSERTしてくれる。
取得してきたものをそのまま更新したい場合は

$obj = $col->findOne();
$obj["name"] = "nazo";
$col->save($obj);
削除

DBの削除

$db->drop();

Collectionの削除

$col->drop();

条件指定でデータを削除

$col->remove(array("name" => "MongoDB"));

条件指定でデータを削除(1つだけ)

$col->remove(array("name" => "MongoDB"), true);

findしたものを削除

$obj = $col->findOne();
$col->remove($obj);

詳しいAPIドキュメント

なんと公式にあるよ!まあPECLだから当たり前?だけど!
http://jp.php.net/mongo