|
Based on v72 (2010-11-14更新) - オリジナル MongoDBは、ドキュメント全体を入れ替える通常のアップデートと、アトミックでin-place(その場で)のアップデートをサポートします。 update()update() は、与えられた条件にマッチするドキュメント全体を新しいオブジェクトで置き換えます。一部の項目だけ更新したい場合には、下記のmodifierを使います。 これがMongoDBの update() のシンタックスです。 db.collection.update( criteria, objNew, upsert, multi ) 引数:
mongoシェルで、 save()mongoシェル 上のsave()コマンドは、一つのオブジェクトをupsertするための簡単なシンタックスです。 // x はJSONスタイルのオブジェクト db.mycollection.save(x); // 存在していたら update、 してなかったらinsert save() は、x が _id フィールドを持っていたら、upsert をし、持っていなければ、 insert をします。そのため、通常、upsertを明示的にリクエストする必要なはく、単に save() を使ってください。 upsert は、 "存在していたら update。していなかったら、 insert" という意味です。 myColl.update( { _id: X }, { _id: X, name: "Joe", age: 20 }, true );
modifier オペレーションmodifier オペレーションは、既存の値をアップデートをとても効率的に行います。たとえば、数値のインクリメントなどに向いています。 通常の方法だと、このようになります。 var j=myColl.findOne( { name: "Joe" } ); j.n++; myColl.save(j); modifierアップデートは、クエリーをしオブジェクトを返す、という部分の遅延を省くことができることが利点です。また、modifierアップデートは、 アトミックな オペレーションで、ネットワーク帯域も少ししか使いません。 このアトミックなアップデートを実行するためには、専用のアップデートオペレータのどれか(必ず'$'で始まります)を指定します。 db.people.update( { name:"Joe" }, { $inc: { n : 1 } } );
これは、 'name'が'joe'である最初のドキュメント探し、 'n' をインクリメントする、ということなります。
$inc{ $inc : { field : value } }
field が存在している場合、 field を value インクリメントします。存在しない場合、 field に value をセットします。 $set{ $set : { field : value } }
field に value をセットします。 $set ではすべての型がサポートされています。 $unset{ $unset : { field : 1} }
fieldを削除します。 v1.3以上の機能です。 $push{ $push : { field : value } }
field がarrayの場合、 value を field に追加します。 field が存在しない場合、 field に [value] をセットします。 field は存在するが、arrayではない場合、 errorが発生します。 $pushAll{ $pushAll : { field : value_array } }
field が存在するarrayの場合、 value_array を一つずつ、 field に追加します。 field が存在しない場合、 field に、 array value_array をセットします。 field は存在するが、arrayではない場合、 errorが発生します。 $addToSet{ $addToSet : { field : value } }
field}}が配列型でかつ、valueが存在しない場合に追加します。 {{field が存在しない場合には、 value を持つ配列をセットします。 {field}} が存在するが、配列型でない場合、エラーになります。 複数の値を追加。 { $addToSet : { a : { $each : [ 3 , 5 , 6 ] } } }
$pop{ $pop : { field : 1 } }
arrayの最後の要素を削除します(バージョン1.1で追加)。 { $pop : { field : -1 } }
arrayの最初の要素を削除します(バージョン1.1で追加)。 $pull{ $pull : { field : _value } }
field からすべての value を削除。 field が存在しているが、arrayでない場合、エラーになります。 完全一致する value に加え、いくつかの書式があります。 { $pull : { field : {field2: value} } } field2 がマッチする値を持つ要素を削除
{ $pull : { field : {$gt: 3} } } 3以上の要素を削除
{ $pull : { field : {<match-criteria>} } } match-criteria に該当する要素を削除
$pullAll{ $pullAll : { field : value_array } }
field がarrayの場合、 value_array の中の値をそれぞれ field からすべて削除します。 field が存在しているが、arrayではない場合、エラーになります。 $renameバージョン 1.7.2 以上。 { $rename : { old_field_name : new_field_name } }
フィールド名を 'old_field_name' から 'new_field_name' へ変更します。 配列内は 'old_field_name' の対象ではありません。 $ ポジションオペレータバージョン 1.3.4 以上 $ オペレータは(それ自身で)、 "クエリでマッチしたアイテムの配列の場所" を意味します。 配列の要素を探し、それを操作する場合に使えます。 たとえば、 > t.find()
{ "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC",
"comments" : [ { "by" : "joe", "votes" : 3 }, { "by" : "jane", "votes" : 7 } ] }
> t.update( {'comments.by':'joe'}, {$inc:{'comments.$.votes':1}}, false, true )
> t.find()
{ "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC",
"comments" : [ { "by" : "joe", "votes" : 4 }, { "by" : "jane", "votes" : 7 } ] }
現在のところ、 $ オペレータは、 クエリでマッチしたアイテムの 最初 のものにのみ適用されます。たとえば、 > t.find();
{ "_id" : ObjectId("4b9e4a1fc583fa1c76198319"), "x" : [ 1, 2, 3, 2 ] }
> t.update({x: 2}, {$inc: {"x.$": 1}}, false, true);
> t.find();
{ "_id" : ObjectId("4b9e4a1fc583fa1c76198319"), "x" : [ 1, 3, 3, 2 ] }
ポジションオペレータは、 upsert と組み合わせることはできません。配列の要素とマッチする必要があるからです。もし、処理の結果、インサートになった場合、 "$" がそのままフィールド名として使われてしまうからです。
upsert と modifiermodifierオペレーションと一緒にupsertを使うことができます。このケースでは、modifier は criteria でアップデート対象のものに適用されます。そしてinsertされたオブジェクトを返します。次に、 upsertで {name:"Joe",x:1,y:1} を insertする例を示します。 db.people.update( { name:"Joe" }, { $inc: { x:1, y:1 } }, true );
いくつかの制限があります。modifierは、 _id フィールドを参照できません。またupdate内の2つ以上のmodifierが同じフィールドを参照できません。たとえば、次の例はできません。 db.people.update( { name:"Joe" }, { $inc: { x: 1 }, $set: { x: 5 } } );
ユニークな値を追加存在していない場合にだけ、arrayに値を追加するには、 バージョン1.3.3から、次のようにできます。 update( {_id:'joe'},{"$addToSet": { tags : "baseball" } } );
それより古いバージョンでは、 $ne : <value> をクエリーに加えてください。 update( {_id:'joe', tags: {"$ne": "baseball"}},
{"$push": { tags : "baseball" } } );
updateリクエストの結果の確認ここまでで紹介したように、 upsert以外のアップデートは存在するオブジェクトをupdateする場合とupdateしない場合があります。upsertは、存在するオブジェクトを更新するか、新しいオブジェクトを追加します。クライアントは、 getlasterror コマンド( db.runCommand( "getlasterror" ) )を続けて実行することで、そのコネクションで起こった直近のコマンドがオブジェクトをアップデートしたかどうかを判断することができます。 getlasterror コマンドの結果が、 updatedExisting を含んでいる場合、 このコネクションでの最後のコマンドは、updateリクエストだった、ということになります。 また updatedExisting がtrueの場合、updateリクエストは既存のオブジェクトをupdateしたことになり、 updatedExisting がfalseの場合には、どのオブジェクトもアップデートされなかったことになります。 注意オブジェクトの padding についてMongoDBで、オブジェクトを更新する場合、オブジェクトのサイズが増えない場合には、更新はin-place(同じ場所)で実行されます。これは、コレクションがたくさんのインデックスを持っている場合、insertのパフォーマンスのために有効です。 Mongoは、コレクション内のオブジェクトが増えているかどうかを学習し、もし増える傾向にある場合、今後のデータの移動を防ぐため、予備の空間(padding)を追加します。この統計は、各コレクション毎に行われます。 ブロックバージョン1.5.2から、大量のデータの更新を安全にできるように、複数のアップデートが同時に起こることがあります。複数のアップデートを、独立して(つまり、処理が行われている間、他の書き込みを許さない)行ないたい場合には、 $atomic フラグを以下のように使います。
db.students.update({score: {$gt: 60}, $atomic: true}, {$set: {pass: true}})
参照 |

IF YOU HAVE A QUESTION, POST IT TO THE USER GROUP.
These pages are fine for comments, but for questions, your best bet will always be the MongoDB User Group. blog comments powered by Disqus