マニュアル
PHP Manual

書き込み

安全な操作

デフォルトでは、書き込み (追加、更新および削除) の際にドライバはデータベースの応答を待ちません。 書き込み操作は高速に行われるけれども、それが実際に成功したのかどうかは判断できないということです。 書き込みに失敗する可能性はいくつか考えられます。ネットワークに問題があったり、 データベースサーバーが停止していたり、単に無効な書き込み操作だったり (システムコレクションに書き込もうとしたなど) といった原因です。

データベースからの応答を取得するには、safe オプションを使います。 このオプションは、すべての書き込み操作で使うことができます。 このオプションを指定すると、データベースに書き込まれたのを確認してから 成功したと判断して結果を返すようになります。書き込みに失敗した場合は、 失敗した原因を示す MongoCursorException() をスローします。

開発中は、常に安全な書き込み操作を行うようにすべきでしょう (キーの重複エラーなどのうっかりミスを防ぐためにも)。 運用時は、それほど "重要でない" データについては安全でない書き込みをしてもよいでしょう。 何が "重要でない" かはアプリケーションによって異なりますが、一般的には (ユーザーが作成するものではなく) 自動的に生成されるデータや秒間数千件のレコードを取得するデータなどを指します。 たとえばクリック追跡データや GPS の位置データなどです。

パフォーマンスへの悪影響を抑えつつ安全な書き込みを行うには、 一連の書き込み操作の最後に安全な書き込みを行うことを推奨します。たとえばこのようになります。

<?php
$collection
->insert($someDoc);
$collection->update($criteria$newObj);
$collection->insert($somethingElse);
$collection->remove($something, array("safe" => true));
?>

そうすれば、もしデータベースに何か問題が発生すれば 最後の書き込みが例外をスローするので気づくことができます。

書き込みの安全性を確かめるためのオプションは、他にもいくつかあります。 "fsync" => true を指定すると、この時点までのすべての書き込みを fsync して強制的にディスクに書き出します (デフォルトでは、MongoDB への書き込みの fsync は一分おきに行われます)。

書き込みを最も安全に行うには、レプリケーションを使い、 最低何台のサーバーへの書き込みが完了したら成功と見なすのかを指定します (運用時には常にレプリケーションを使うべきです。レプリカセットに関する詳細な情報は "接続" のセクションを参照ください)。

<?php
$collection
->insert($someDoc, array("safe" => 3));
?>

"safe" => N と設定すると、最低 N 台のサーバーに書き込みが反映されるまで MongoDB サーバーは書き込みに成功したと判断しません。 つまり、N を 3 にすると、 マスタと 2 台のスレーブには確実に書き込まれたことになります。

ネストしたオブジェクトの更新

次のドキュメントで、コメントの author を変更することを考えましょう。

{ 
    "_id" : ObjectId("4b06c282edb87a281e09dad9"), 
    "content" : "this is a blog post.",
    "comments" : 
    [
        {
            "author" : "Mike",
            "comment" : "I think that blah blah blah...",
        },
        {
            "author" : "John",
            "comment" : "I disagree."
        }
    ]
}
内部のフィールドを変更するには、$set (他のフィールドが削除されてしまわないように!) を使って変更したいコメントのインデックスを指定します。
<?php

$blog
->update($criteria, array('$set' => array("comments.1" => array("author" => "Jim"))));

?>

位置指定演算子

位置指定演算子 $ は、配列内のオブジェクトを更新するときに有用です。 たとえば上の例で、実際に変更したいコメントのインデックスがわからないけれども "John" を "Jim" に変更しなければならないという状況を考えてみましょう。 そんなときには $ が使えます。

<?php

$blog
->update(
    array(
"comments.author" => "John"), 
    array(
'$set' => array('comments.$.author' => "Jim")));

?>

マニュアル
PHP Manual