2012-02-10 18 views
17

新しいフィールドの値を既存のフィールドの値に設定して、コレクションに新しいフィールドを追加したいとします。 (このコレクションの新しいドキュメントはすべて、この独特の冗長性を持っていませんが、私が欲しい既存のフィールドの値を持つコレクションに新しいフィールドを追加する

# db.foo.findOne() 
    { 
     "_id"  : ObjectId("4f25c828eb60261eab000000"), 
     "created" : ISODate("2012-01-29T16:28:56.232Z"), 
     "event_ts" : ISODate("2012-01-29T16:28:56.232Z"), #same as created 
     "..."  : ... 
    } 

:これまで

# db.foo.findOne() 
    { 
     "_id"  : ObjectId("4f25c828eb60261eab000000"), 
     "created" : ISODate("2012-01-29T16:28:56.232Z"), 
     "..."  : ... 
    } 

具体的には、私がこれから行きたいです私の既存の文書でこれを行うには)

+0

これは一度だけ行う必要がありますか? – ggreiner

+0

右、このデータを準備するために一度だけ行う必要があります – Purrell

答えて

38
function addEventTsField(){ 
    db.foo.find().forEach(function(doc){ 
     db.foo.update({_id:doc._id}, {$set:{"event_ts":doc.created}}); 
    }); 
} 

コンソールから実行:

を:(パフォーマンスが問題であれば、あなたのケースで _id、および createdあなただけ specific fieldsを読み込むことができます)
addEventTsField(); 
+2

しかし、原子的な操作ではありません。これらは、2つの別々の操作であり、その間でデータが変更される可能性があります。 (彼は恐らく彼がおそらく安全だと思うが、それはオフラインで一度やっているようだ) – UpTheCreek

2

いいえ、できません。

  1. ドキュメントを読み込むには、次の2つの手順が必要です。文書の
  2. アトミックアップデート(ロードされたcreatedフィールドを使用してevent_tsを設定)
+0

db.foo.find()。forEach()で何かをしていなくても? – Purrell

+1

@Purrell: 'forEach'は実際に見つかったすべてのドキュメントを読み込み、2つのステップの更新になります... –

-1

あなたのコードはevent_tsの処理方法を既に知っているので、なぜデータをコピーする必要がありますか?あなたの代わりにフィールドの名前を変更することができます。それを行うために1時間の事、その大したことない場合には

{ $rename : { old_field_name : new_field_name } } 

http://www.mongodb.org/display/DOCS/Updating

+4

あなたは「作成された」ということはドキュメントにも必要ではないという前提を作っている。 – Purrell

-1

を参照してください。 "db.foo.find();"のようなクエリを実行します。あなたのモンゴーシェルフで、TextpadやSublimeテキストのようなエディタに出力全体を貼り付けるには、列ブロック(Ctrl +スクロールホイールで&ドラッグ)をクリックして別のフィールドに拡張し、新しく名前を変更しますあなたがそれを望むように貼り付けられた列は、一度、 "db.foo.insert({"と "}");で "^"として全体の束を編集する正規表現を行う;

以下の手順のようです。

  1. あなたは { 'フィールド1':値 'FIELD2':値2、 'FIELD3':value4}のように出力を貼り付けます。
    1. 最後のセットをコピーし、エディタ列ブロックを使用して拡張します。 {'field1':value、 'field2':value2、 'field3':value4};
    2. 適切な単語を挿入して、mongoのコマンドのようにします。 db.foo.insert({'field1':value、 'field2':value2、 'field3':value4});
    3. これらをすべてコピーして、mongoシェルに貼り付けます。それは、あなたが望むようにあなたのためにすべてを行うだけです。それを一度テストし、コレクションをクリーンアップした直後にすべてをやり直します。それ以外の場合は、重複を挿入します。再度挿入しようとすると衝突するので、出力の "_id"フィールドも削除してください!

は今、あなたのエディタ内のすべての単一の行は、あなたのコレクションに新しい文書を挿入するためにあなたのシェルに貼り付けることができる有効なのmongoコマンドを示しています。一度テストすればうまく動作し、 "db.foo.remove({})"のようなコレクション全体をクリーンアップできます。 giffyでそれを行うエディタからコマンド全体を貼り付けます。

最初に試してみると難しいかもしれませんが、それが正しいとすれば、いつでも好きなときに一緒に働くことができます。

+0

このエラーは、エラーが起こりやすく、自動化できない、テストできない、スクリプトできないなどの理由でも意味がありません...なぜこの操作をエディタで実行したいのですか?簡単な関数とforEach()で簡単に行うことができますか? –

+0

また、操作の途中で 'db.foo.remove({}) 'が必要であるため-1です。これは、既存のデータがまだそこにあることを期待しているものを壊します。 – David

+0

質問は一度だけの仕事であるという意図で掲示されました。また、エディタでそれを実行すると、編集する必要があるもの、何をコメントするのか、削除するべきものがずっと簡単になります。もちろん、foreachを使用したソリューションは優れていますが、これはそれほど悪くはありません。なぜなら、テストの途中でかなり頻繁にデータを挿入し、それらを削除し、そこにいくつかの変更を加えて再度追加する必要があるときですコマンドラインで同じスクリプトファイルを実行するだけで自動化することもできます。 – Param

関連する問題