MongoCollection
在线手册:中文 英文
PHP手册

MongoCollection::update

(PECL mongo >=0.9.0)

MongoCollection::updateUpdate records based on a given criteria

说明

public bool|array MongoCollection::update ( array $criteria , array $new_object [, array $options = array() ] )

参数

criteria

Description of the objects to update.

new_object

The object with which to update the matching records.

options

This parameter is an associative array of the form array("optionname" => <boolean>, ...). Currently supported options are:

  • "upsert"

    If no document matches $criteria, a new document will be created from $criteria and $new_object (see upsert example below).

  • "multiple"

    All documents matching $criteria will be updated. MongoCollection::update() has exactly the opposite behavior of MongoCollection::remove(): it updates one document by default, not all matching documents. It is recommended that you always specify whether you want to update multiple documents or a single document, as the database may change its default behavior at some point in the future.

  • "safe"

    Can be a boolean or integer, defaults to FALSE. If FALSE, the program continues executing without waiting for a database response. If TRUE, the program will wait for the database response and throw a MongoCursorException if the update did not succeed.

    If you are using replication and the master has changed, using "safe" will make the driver disconnect from the master, throw and exception, and attempt to find a new master on the next operation (your application must decide whether or not to retry the operation on the new master).

    If you do not use "safe" with a replica set and the master changes, there will be no way for the driver to know about the change so it will continuously and silently fail to write.

    If safe is an integer, will replicate the update to that many machines before returning success (or throw an exception if the replication times out, see wtimeout). This overrides the w variable set on the collection.

  • "fsync"

    Boolean, defaults to FALSE. Forces the update to be synced to disk before returning success. If TRUE, a safe update is implied and will override setting safe to FALSE.

  • "timeout"

    Integer, defaults to MongoCursor::$timeout. If "safe" is set, this sets how long (in milliseconds) for the client to wait for a database response. If the database does not respond within the timeout period, a MongoCursorTimeoutException will be thrown.

返回值

If safe was set, returns an array containing the status of the update. Otherwise, returns a boolean representing if the array was not empty (an empty array will not be inserted). The fields in this array are decribed in the documentation for MongoCollection::insert().

错误/异常

Throws MongoCursorException if the "safe" option is set and the update fails.

Throws MongoCursorTimeoutException if the "safe" option is set and the operation takes longer than MongoCursor::$timeout milliseconds to complete. This does not kill the operation on the server, it is a client-side timeout.

更新日志

版本 说明
1.0.1 Changed "options" parameter from boolean to array. Pre-1.0.1, the second parameter was an optional boolean value specifying an upsert.
1.0.5 Added "safe" option.
1.0.9 Added ability to pass integers to "safe" options (only accepted booleans before) and added "fsync" option.
1.0.9 The return type was changed to be an array containing error information if the "safe" option is used, otherwise it is a boolean as before.
1.0.11 Disconnects on "not master" errors if "safe" is set.
1.2.0 Added timeout option.
1.3.0 The options parameter does no longer accept just a boolean to signify an upsert. Instead, this now has to be done with array('upsert' => true).

范例

Example #1 MongoCollection::update()

Adding an address field to a document.

<?php

$c
->insert(array("firstname" => "Bob""lastname" => "Jones" ));
$newdata = array('$set' => array("address" => "1 Smith Lane"));
$c->update(array("firstname" => "Bob"), $newdata);

var_dump($c->findOne(array("firstname" => "Bob")));

?>

以上例程的输出类似于:

array(4) {
  ["_id"]=>
  object(MongoId)#6 (0) {
  }
  ["firstname"]=>
  string(3) "Bob"
  ["lastname"]=>
  string(5) "Jones"
  ["address"]=>
  string(12) "1 Smith Lane"
}

Example #2 MongoCollection::update() upsert example

Upserts can simplify code, as a single line can create the object if it does not exist yet and update it if it does.

<?php

$c
->drop();
$c->update(array("uri" => "/summer_pics"), array('$inc' => array("page hits" => 1)), array("upsert" => true));
var_dump($c->findOne());

?>

以上例程的输出类似于:

array(3) {
  ["_id"]=>
  object(MongoId)#9 (0) {
  }
  ["uri"]=>
  string(12) "/summer_pics"
  ["page hits"]=>
  int(1)
}

If $new_object does not contain $-operators, an upsert will create a new document from the passed fields only. This matches the behavior of a normal update, where not using $-operators causes the whole document to be overwritten.

<?php

$c
->drop();
$c->update(
    array(
"name" => "joe"),
    array(
"username" => "joe312""createdAt" => new MongoDate()), 
    array(
"upsert" => true)
);
var_dump($c->findOne());

?>

以上例程的输出类似于:

array(3) {
  ["_id"]=>
  object(MongoId)#10 (0) {
  }
  ["username"]=>
  string(6) "joe312"
  ["createdAt"]=>
  object(MongoDate)#4 (0) {
  }
}

Example #3 MongoCollection::update() multiple example

By default, MongoCollection::update() will only update the first document matching $criteria that it finds. Using the "multiple" option can override this behavior, if needed.

This example adds a "gift" field to every person whose birthday is in the next day.

<?php

$today 
= array('$gt' => new MongoDate(), '$lt' => new MongoDate(strtotime("+1 day")));
$people->update(
    array(
"birthday" => $today),
    array(
'$set' => array('gift' => $surprise)),
    array(
"multiple" => true)
);

?>

参见

The PHP documentation on updates and the » MongoDB core docs.


MongoCollection
在线手册:中文 英文
PHP手册
PHP手册 - N: Update records based on a given criteria

用户评论:

nerds at limeworks dot com dot au (22-Aug-2011 10:39)

For anyone referencing records by the Mongo _id object, it's important to recognise that it is in fact an object, and not a string.

If you have a record with a Mongo ID of say "4e519d5118617e88f27ea8cd" that you are trying to retrieve or update, you cannot search for it using something like:
<?php
$m
= new Mongo();
$db = $m->selectDB('db');
$collection = 'collection';
$db->$collection->findOne(array('_id', '4e519d5118617e88f27ea8cd'));
?>

There is some documentation that mentions simple conversion to string will solve this, but I have found the only reliable way to locate records based on their ID is to first pass it to MondoID(), then use that for reference.

Something like this will be far more reliable:
<?php
$m
= new Mongo();
$db = $m->selectDB('db');
$collection = 'collection';
$mongoID = new MongoID('4e519d5118617e88f27ea8cd');
$db->$collection->findOne(array('_id', $mongoID));
?>

This may prove useful for anyone using the ID object like an auto-increment database key would be used in MySQL or similar.

joshuadburns at hotmail dot com (08-Nov-2010 08:51)

Please note under optional third parameter "options":

While the official MongoDB documentation references the keyword "multi" to flag the use of multiple updates, the PHP implementation uses the key "multiple" instead.

This may cause a little confusion if you're basing your keys on the OFFICIAL MongoDB documentation.

rithish[at]gmail[dot]com (02-Nov-2010 01:22)

Do note, for incrementing a value using $inc, typecast the value to an integer before passing the new object to update().

<?php
$votes
= (int) $votes;
$newData = array('$inc' => array('votes'=>$votes));
$c->update(array("firstname" => "Bob"), $newData);
?>

This is especially noteworthy, if you are taking values from $_GET and pushing them for increment.

jeff at canuckistani dot ca (17-Sep-2010 11:05)

The return type of update changed in 1.09 if you are using safe => TRUE. It now returns something that looks like the info returned by MongoDB::lastError:

Array
(
    [err] =>
    [updatedExisting] => 1
    [n] => 1
    [ok] => 1
)