Writes

Safe Operations

By default, the driver does not wait for a database response to writes (inserts, updates, and deletes). This means that writes can be performed extremely quickly, but you don't know whether or not they actually succeeded. Writes can fail for a number of reasons: if there are network problems, if a database server goes down, or if the write was simply invalid (e.g., writing to a system collection).

To get a response from the database, use the safe option, available for all types of writes. This option will make sure that the database has the write before returning success. If the write failed, it will throw a MongoCursorException() with an explanation of the failure.

While developing, you should always use safe writes (to protect against inadvertent mistakes, such as duplicate key errors and similar). In production, unsafe writes can be used for "unimportant" data. Unimportant data varies on application, but it's generally automatically (instead of user generated) data, such as click tracking or GPS locations, where you can get thousands of records per second.

To safely perform writes without incurring too large a performance penalty, it is recommended that you do a safe write at the end of a series of writes. For example:

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

Then, if the last write throws an exception, you know that there's a problem with your database.

There are a few other options available to ensure the safety of writes. You can specify "fsync" => true to force the database to fsync all writes up to this point to disk (by default, MongoDB fsyncs writes once per minute).

The safest way of doing a write is to use replication and specify the number of servers that must have this write before returning success. (You should always use replication in production, see the Connecting section for more information on replica sets.)

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

If you specify "safe" => N, the MongoDB server will make sure that at least N servers have a copy of the write before returning success. So, if N is 3, the master and two slaves must have the write.

Updating Nested Objects

Suppose we wish to change the name of a comment's author in this document:

{ 
    "_id" : ObjectId("4b06c282edb87a281e09dad9"), 
    "content" : "this is a blog post.",
    "comments" : 
    [
        {
            "author" : "Mike",
            "comment" : "I think that blah blah blah...",
        },
        {
            "author" : "John",
            "comment" : "I disagree."
        }
    ]
}
In order to change an inner field, we use $set (so that all of the other fields are not removed!) with the index of comment to change:
<?php

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

?>

The Positional Operator

The positional operator $ is useful for updating objects that are in arrays. In the example above, for instance, suppose that we did not know the index of the comment that we needed to change, merely that we needed to change "John" to "Jim". We can use $ to do so.

<?php

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

?>