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")));
?>