指定した条件にもとづいてレコードを更新する

# MongoCollection::update

(PECL mongo >=0.9.0)

MongoCollection::update — 指定した条件にもとづいてレコードを更新する

### 説明

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

### パラメータ

`criteria`

  更新したいオブジェクトの条件。

`new_object`

  マッチするレコードを更新するオブジェクト。 更新演算子を含めたり (特定のフィールドだけの更新用)、 ドキュメント全体を上書きしたりできます。

`options`

  更新時のオプションの配列。 現在利用可能なオプションは、以下のとおりです。

  - "upsert"

    `$criteria` にマッチするレコードが見つからない場合に 新しいドキュメントを追加します。

    新しいドキュメントを追加するときに `$new_object` にアトミックな修正子 ($ 演算子) が含まれていれば、この操作を `$criteria` パラメータに適用して新しいドキュメントを作ります。 `$new_object` がアトミックな修正子を含まない場合は、 そのままの形式で新しいドキュメントに使います。 詳細は、以下の upsert の例を参照ください。

  - "multiple"

    $criteria にマッチするすべてのドキュメントを更新します。 MongoCollection::update() は MongoCollection::remove() と正反対の動きをします。 デフォルトでは、マッチするすべてのドキュメントではなく ひとつのドキュメントだけを更新するのです。 複数ドキュメントを更新したいのかそうでないのかは、 常に指定しておくことを推奨します。 将来、データベースのデフォルトの挙動が変わる可能性があるからです。

  - "fsync"

    Boolean 型で、デフォルトは `FALSE` です。 ジャーナリングが有効な場合、これは "j" とまったく同じ動きをします。 ジャーナリングが有効でない場合は、追加をディスク上のデータベースファイルに同期させるまで成功したと見なさないようになります。 `TRUE` にすると確認つき書き込みが暗黙のうちに設定され、"w" の値を 0 にします。

    > 注意: ジャーナリングが有効な場合は、"fsync" のかわりに "j" を使いましょう。 "fsync" と "j" を同時に指定すると、エラーになります。

  - "j"

    デフォルトは `FALSE` です。これを指定すると、追加をジャーナルに同期させるまで成功したと見なさないようになります。`TRUE` にすると確認付き書き込みと見なされ、"w" の設定を 0 に上書きします。

    > 注意: このオプションを使っているときにジャーナリングを無効にすると、MongoDB 2.6 以降ではエラーが発生して書き込みに失敗します。古いバージョンのサーバーでは、単純にオプションの指定を無視します。

  - "socketTimeoutMS"

    このオプションは、ソケット通信の制限時間を、ミリ秒単位で指定します。この時間内にサーバーからの反応がなければ、MongoCursorTimeoutException をスローします。この場合、サーバー側で書き込み処理が行われたのかどうかを判断できなくなります。-1 を指定すると、永遠にブロックします。MongoClient のデフォルト値は 30000 (30 秒) です。

  - "w"

    WriteConcerns を参照ください。MongoClient でのデフォルト値は 1 です。

  - "wTimeoutMS"

    このオプションは、書き込み確認を待つ制限時間をミリ秒単位で指定します。これが書き込み操作に適用されるのは、"w" が 1 より大きい場合のみです。というのも、タイムアウトはレプリケーションに関する機能だからです。この時間内に書き込み確認ができなかった場合は MongoCursorException をスローします。0 を指定すると、永遠にブロックし続けます。MongoClient でのデフォルトは 10000 ミリ秒 (10 秒) です。

  以下のオプションは廃止予定です。使ってはいけません。

  - "safe"

    非推奨。write concern の w オプションを使いましょう。

  - "timeout"

    非推奨。"socketTimeoutMS" のエイリアス。

  - "wtimeout"

    廃止予定。"wTimeoutMS" のエイリアスです。

### 返り値

"w" が設定されていれば、更新の状態を表す配列を返します。 それ以外の場合は `TRUE` を返します。

状態を表す配列のフィールドについては MongoCollection::insert() のドキュメントを参照ください。

### エラー / 例外

"w" オプションが設定されていて書き込みが失敗した場合に MongoCursorException をスローします。

"w" オプションの値が 1 より大きく設定されていて、操作の完了までの時間が MongoCursor::$timeout ミリ秒をこえた場合に MongoCursorTimeoutException をスローします。サーバー上での操作は止めません。これはクライアント側でのタイムアウトです。MongoCollection::$wtimeout はミリ秒です。

### 変更履歴

バージョン | 説明
--- | ---
1.5.0 | "wTimeoutMS" オプションが追加されました。これは "wtimeout" を置き換えるものです。 "wtimeout" を使うと `E_DEPRECATED` が発生します。 "socketTimeoutMS" オプションが追加されました。これは "timeout" を置き換えるものです。 "timeout" を使うと `E_DEPRECATED` が発生します。 "safe" を使うと `E_DEPRECATED` が発生します。
1.3.4 | "wtimeout" オプションが追加されました。
1.3.0 | "w" オプションが追加されました。 `options` パラメータで、boolean だけを渡して upsert を指定することができなくなりました。 同じことをするには array('upsert'' => true) としなければなりません。
1.2.11 | `options` が scalar のときに `E_DEPRECATED` を発行するようになりました。
1.2.0 | "timeout" オプションが追加されました。
1.0.11 | "safe" が設定されている場合は、"not master" エラーで接続を切断するようになりました。
1.0.9 | "safe" オプションに整数値がわたせるようになりました (以前は boolean のみでした)。 "fsync" オプションが追加されました。 "safe" オプションを使っている場合の返り値の型が配列に変わりました。 配列にはエラー情報が含まれています。"safe" オプションを使わない場合は、今までどおり boolean のままです。
1.0.5 | "safe" オプションが追加されました。
1.0.1 | `options` パラメータが boolean から配列に変わりました。 1.0.1 より前のバージョンでは二番目のパラメータはオプションの boolean 値で、upsert を指定するものでした。

### 例

例1 MongoCollection::update()

address フィールドをドキュメントに追加します。

`<?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"
    }

例2 MongoCollection::update() での upsert

upsert を使うとコードを簡潔にすることができます。 オブジェクトが存在しない (`$criteria` に基づく) 場合は新たに作成し、 存在する場合はそれを更新するという操作を一行で書けるからです。

次の例では、`$new_object` にアトミックな修正子が含まれています。 コレクションは空なので upsert は新たなドキュメントを追加することになり、 これらの操作を `$criteria` パラメータに適用してドキュメントを作ります。

`<?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)
    }

`$new_object` がアトミックな修正子 ($ 演算子) を含まない場合、upsert は `$new_object` をそのままの形式で新しいドキュメントに使います。 これは通常の update の挙動と同じです。 アトミックな修正子を使わなければ、ドキュメント全体が上書きされます。

`<?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) {
      }
    }

例3 MongoCollection::update() での複数更新

デフォルトでは MongoCollection::update() は、 `$criteria` にマッチするドキュメントが複数見つかっても最初のものだけを更新します。 必要なら、"multiple" オプションでその挙動を変えることができます。

この例は、翌日が誕生日である全員に "gift" フィールドを追加します。

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

### 参考

更新に関するドキュメント および » MongoDB コアメント を参照ください。