2011-12-01 9 views
25

私は、既存の数値フィールドを使用して式を使用して変更する更新ステートメントを作成する方法を探していました。たとえば、Priceというフィールドがある場合、Priceを既存の値の50%に設定する更新を行うことは可能ですか?Mongodbの値でフィールドを掛ける

だから、私はdb.collection.update({tag : "refurb"}, {$set {Price : Price * 0.50 }}, false, true);

を行うにはしたいと思い与え{ Price : 19.99 }

この行うことができますか私は更新し、クライアントに戻す値を読み取り、変更することがありますか?私は質問が次に更新で使用されることができ、更新される文書を参照できるかどうかを推測します。

+3

モンゴの次期バージョンでは、あなたがこのすべてはevalなしにこれを行うことに注意してDBを無償でほとんどロックしてください。新しいデベロッパーが時代遅れの情報を使用しないように、新しい答えを確認して受け入れるかもしれません。 –

答えて

34

db.eval()でサーバー側のコードを実行できます。

db.eval(function() { 
    db.collection.find({tag : "refurb"}).forEach(function(e) { 
     e.Price = e.Price * 0.5; 
     db.collection.save(e); 
    }); 
}); 

これはDBをブロックするので、検索更新操作のペアを実行することをお勧めします。

はまあ、これはセット$としてアトミックな操作で可能であるhttp://www.mongodb.org/display/DOCS/Server-side+Code+Execution

+0

ありがとうございます。あなたはあなたが示したようにeval()を使うべきであると言っていますか、またはブロックすることを避けるためにfind/updateを使ってクライアント側で行うべきですか? – Brad

+1

@Bradこの特定の更新操作の全体的なコストを評価する必要があります。操作が長くなる場合(コレクション内の多くのドキュメントが更新されます)、evalは使用しないでください。ドキュメントを最初に照会し、インプレース更新ではなく更新するのに大きなオーバーヘッドはありません。特に大きな文書を検索するフィールドを制限し、カバーされたインデックス機能(http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields#RetrievingaSubsetofFields-CoveredIndexes)を使用する場合は、 – pingw33n

+1

、ありがとう。私はまた、eval()がシャーディングではうまくいかないことを知っています。 Nolockは面白いです。 – Brad

-1

を参照してください。

  • はあなたが現在の値を取得し、あなたの場合セット
  • でそれを変更するために変更したいドキュメントを取得pingw33n
  • が提案したのeval()ソリューションを使用します。

    あなたはいくつかのオプションを持っています(以前のソリューションを使用して)値をフェッチしている間にドキュメントが変更されていないことを確認したい場合は、findAndModify(操作のヒントを得るにはthis pageを参照)操作を使用することができます。

これは本当にあなたのコンテキストに依存しています:データベースに非常に低い圧力で、私はpingw33nの解決策に行きます。非常に高い稼働率で、私は3番目のソリューションを使用します。

+0

ありがとうございます。私は、findAndModifyがどのように式を使用することができるかを見ていない。これが私の主な目標だった。 – Brad

+0

@Brad findAndModifyでは式の使用が許可されていますが、2段階のアクションを実行できます。取得後に変更されていない場合に限り、アイテムを最初に取得してから更新します(50%削減で更新) – kamaradclimber

19

Mongo 2.6.xには、$mul operatorがあります。フィールドの値に数値を掛けると、次の構文になります。

{ 
    $mul: { field: <number> } 
} 

だからあなたの場合には次の操作を実行する必要があります。

db.collection.update(
    { tag : "refurb"}, 
    { $mul: { Price : 0.5 } } 
); 
+1

私は十分に高くないコメントするにはrep、それ以外の場合は、私を助けたが、間違ったフォーマットを持つSalvador Daliによる上記のコメントになります。実際には次のようになります:{$ mul:{field:}} {field:{$ mul:}} – Wake

関連する問題