2012-01-26 23 views
1

This pageは、以前に取り出された(find)ドキュメントに到達し、それを更新するためにサブエレメント(配列)に問い合わせる更新を示します。私はまったく同じことをする必要があります。例えばコード:mongodb find更新セマンティクス

> 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) 

のfind-続い・バイ・更新を管理するルールはどのようなものがあり、私は、ドキュメントで、このための説明を気づいていません。ドライバー経由でmongodbの使用にも同じことが適用されますか?関連するセマンティクスへのリンクが役立ちます。私はC++ドライバを使用しています。

編集:自己答え

2つのコマンドが1にロールバックすることができます(これは、この質問が提起曖昧さを除去する一つの方法である)、更新のクエリ部分は、配列を参照することができ、サブ要素には、$シンボルが参照されます。私はあなたが更新操作のクエリ部分で1つのサブ要素のみを参照できると仮定します。次のように私の場合は、更新操作が見えます:

db.qrs.update ({ "_id" : ObjectId("4f1fa126adf93ab96cb6e848"), "urls.u_id" : 171 }, { "$inc" : { "urls.$.CC": 1} }) 

_id正しく右の一意の行「素数」と、2番目のクエリ要素"urls.u_id" : 171は、問題の行が右側のフィールドを持っていることを保証します。 urls.$.CC次に、$incオペレーションを正しいアレイエントリにルーティングします。どんなのMongoDB DEVまたは原稿ライタ

recomendationは、それらの潜在的な競合状態を持っている例を表示しません。原子的に実行可能な複数の操作を表示しないようにしてください。

+0

@self回答です。例が2ステップ操作を示していると間違っています。それはしません。著者は、コレクション内の文書の構造を、単に更新例を示す前に、findで読者に提示しています。 –

答えて

2

このルールは比較的簡単です。更新の結果は、いくつかの事柄に依存して、後続の読み取りで利用可能かどうかは関係ありません(slaveSetのtrue/false、異なる接続を使用した更新と検索、安全性の書き込み)。安全な書き込み(w> = 1)を実行して同じ接続で検索を実行すると、それが利用可能であることを保証できます。ほとんどのドライバは、この機能を提供しています(通常は "requestStart"と "requestDone")。

これまでにfindAndModifyというより良い解決策がありました。この操作では、ドキュメントが検索され、ドキュメントが更新され、ドキュメントの古いバージョンまたは新しく更新されたバージョンが返されます。このコマンドは、C++ドライバで使用できます。参照のためにここに:http://www.mongodb.org/display/DOCS/findAndModify+Command

EDIT:この例の "find"は、コレクション内のドキュメントの構造/スキーマが、文脈で「更新」する。 "更新"操作は決してその前の "検索"の影響を受けません。

+0

私は見つける後のルールを意味しました。 't.update({'comments.by':' joe'} ...) 'は、以前の検索操作で一意に識別されたオブジェクトを参照しています。検索の結果、以前の一意の行が見つかった場合は、後続の更新操作で利用できるようになります。:D –

+0

Hm?いいえ、お互いに関係ありません。検索はイラストだけにあり、形や形がそれに続く更新操作に影響を与えることはありません。 –

+0

その場合、すべての記事で「ジョーによるコメント」の投票数を更新するという質問がありますか?これは、その例題が説明しようとしていることですか?最初の発見は、特定の記事をプライムします。実例と現実的なユースケースとして、特定の記事内のコメントにアップヴォートがある場合にのみ意味をなさないでしょう。 –