7

私は MongoDB をまったく初めて使用します...「初心者」タグがありません。専門家はこの質問を見る必要はありません。

式を使用してコレクション内のすべてのドキュメントを更新しようとしています。これを解決することを期待していたクエリは次のとおりです。

db.QUESTIONS.update({}, { $set: { i_pp : i_up * 100 - i_down * 20 } }, false, true);

ただし、次のエラー メッセージが表示されます。

ReferenceError: i_up が定義されていません (シェル):1

同時に、データベースはこれを食べても問題はありませんでした:

db.QUESTIONS.update({}, { $set: { i_pp : 0 } }, false, true);

一度に 1 つずつドキュメントを作成する必要がありますか? それは非常に複雑に思えます。

更新 うまくいかないことを教えてくれた Sergio Tulentsev に感謝します。今、私はこれを行う方法に本当に苦労しています。MongoDB が理解できる方法でこれを書くことができる親切な魂に500利益ポイントを提供します。私たちのフォーラムに登録すると、そこであなたのアカウントに利益ポイントを追加できます。

4

5 に答える 5

6

次のようなSQLに相当するMongoDBを検索しているときに、これに出くわしました。

update t
set c1 = c2
where ...

Sergio は、直接の更新では別のプロパティを値として参照できないという点で正しいです。ただし、カーソルをdb.c.find(...)返し、そのカーソルにはforEachメソッドがあります。

MongoDB へのクエリは、結果を取得するために反復できるカーソルを返します。クエリの正確な方法は、言語ドライバーによって異なります。mongo以下の詳細は、MongoDB シェル (つまりプロセス)からのクエリに焦点を当ててい ます。

シェルfind()メソッドは、結果から特定のドキュメントを取得するために反復できるカーソル オブジェクトを返します。この目的のためにhasNext()およびメソッドを使用 します。next()

for( var c = db.parts.find(); c.hasNext(); ) {
   print( c.next());
}

さらに、シェルでforEach()は、カーソルで使用できます。

db.users.find().forEach( function(u) { print("user: " + u.name); } );

したがって、次のようなことが言えます。

db.QUESTIONS.find({}, {_id: true, i_up: true, i_down: true}).forEach(function(q) {
    db.QUESTIONS.update(
        { _id: q._id },
        { $set: { i_pp: q.i_up * 100 - q.i_down * 20 } }
    );
});

MongoDB を離れることなく、一度に 1 つずつ更新します。

ドライバーを使用して MongoDB に接続している場合は、JavaScript の文字列を MongoDB に送信する方法が必要です。たとえば、Ruby ドライバーを使用する場合は、次のようにしますeval

connection.eval(%q{
    db.QUESTIONS.find({}, {_id: true, i_up: true, i_down: true}).forEach(function(q) {
        db.QUESTIONS.update(
            { _id: q._id },
            { $set: { i_pp: q.i_up * 100 - q.i_down * 20 } }
        );
    });
})

他の言語も同様のはずです。

于 2012-11-29T03:07:59.127 に答える
5

更新では式を使用できません。むしろ、ドキュメントのフィールドに依存する式は使用できません。自己完結型の単純な数式は問題ありません (例: 2 * 2)。

他のフィールドの関数であるすべてのドキュメントに新しいフィールドを設定する場合は、それらをループして手動で更新する必要があります。マルチアップデートはここでは役に立ちません。

于 2012-04-16T19:54:31.547 に答える
2

//the only differnce is to make it look like and aggregation pipeline
db.table.updateMany({}, [{
      $set: {
        col3:{"$sum":["$col1","$col2"]}
      },
    }]
 )

于 2021-04-09T10:29:34.803 に答える
0

発信者 ID の先頭から「00」を削除する例:

db.call_detail_records_201312.find(
    { destination: /^001/ }, 
    { "destination": true }
).forEach(function(row){
    db.call_detail_records_201312.update(
        { _id: row["_id"] },
        { $set: {
                destination: row["destination"].replace(/^001/, '1')
            }
        }
    )
});
于 2014-01-30T11:26:20.837 に答える