アプリケーションのニーズに応じて、スコアを計算するための集計フレームワークを使用し、 bullkWrite()
コレクションを更新します。 $ project
算術演算子を使用したスコア計算の余地としてのパイプラインステップ。
C3
を計算するためのロジック以降 あなたの質問では、 1
から番号を取得しています 7
へ これは正確に7に等しい-ポイント数(。)
、私が考えることができる唯一の実行可能なアプローチは、集計を行う前に、最初にこの値を保持する追加のフィールドを格納することです。したがって、最初のステップはその追加フィールドを作成することであり、 bullkWrite()
次のように:
ステップ1:追加の daysInWeek
に対応するようにスキーマを変更します フィールド
var counter = 0, bulkUpdateOps = [];
db.collection1.find({
"Field5": { "$exists": true }
}).forEach(function(doc) {
// calculations for getting the number of points in Field5
var points, daysInWeek;
points = (doc.Field5.match(new RegExp(".", "g")) || []).length;
daysInWeek = 7 - points;
bulkUpdateOps.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": {
"$set": { "daysInWeek": daysInWeek }
}
}
});
counter++;
if (counter % 500 == 0) {
db.collection1.bulkWrite(bulkUpdateOps);
bulkUpdateOps = [];
}
});
if (counter % 500 != 0) { db.collection1.bulkWrite(bulkUpdateOps); }
理想的には、上記の操作は、質問内の他の定数の計算に対応できるため、 Field8
を作成することもできます。 結果として。ただし、このような計算はクライアントで実行し、MongoDBにサーバーで最適な処理を実行させる必要があると思います。
ステップ2:集計を使用して Field8
を追加します フィールド
その余分なフィールドを作成したdaysInWeek
次に、のコホートを使用して、新しい変数を投影する集計パイプラインを構築できます。算術演算子
計算を実行します(ここでも、アプリケーション層でこのような計算を実行することをお勧めします)。最終的な投影は、計算されたフィールドの積になります。計算されたフィールドは、集計結果カーソルを使用して、 Field8
を繰り返して追加できます。 各ドキュメントのコレクションへ:
var pipeline = [
{
"$project": {
"C1": {
"$add": [
10,
{ "$multiply": [ "$Field3", 0.03 ] }
]
},
"C2": {
"$cond": [
{ "$eq": [ "$Field2", 1 ] },
1,
0.03
]
},
"C3": "$daysInWeek",
"C4": {
"$cond": [
{ "$eq": [ "$Field2", 1 ] },
{ "$pow": [ "$Field4", -0.6 ] },
1
]
}
}
},
{
"$project": {
"Field8": { "$multiply": [ "$C1", "$C2", "$C3", "$C4" ] }
}
}
],
counter = 0,
bulkUpdateOps = [];
db.collection1.aggregate(pipeline).forEach(function(doc) {
bulkUpdateOps.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": {
"$set": { "Field8": doc.Field8 }
}
}
});
counter++;
if (counter % 500 == 0) {
db.collection1.bulkWrite(bulkUpdateOps);
bulkUpdateOps = [];
}
});
if (counter % 500 != 0) { db.collection1.bulkWrite(bulkUpdateOps); }
MongoDBの場合>=2.6
および<=3.0
、 Bulk OpeartionsAPI
を使用します カーソルのを使用してコレクションを反復処理する必要がある場合forEach()
上記の集計パイプラインの算術演算子の一部は、MongoDB > =2.6
では使用できません。 および<=3.0
したがって、 内で計算を行う必要があります。 forEach()
反復。
バルクAPIを使用して、各更新を一括でバンドルし、処理のためにコレクション内の500ドキュメントごとに1回だけサーバーに送信することで、サーバー書き込み要求を減らします。
var bulkUpdateOps = db.collection1.initializeUnorderedBulkOp(),
cursor = db.collection1.find(), // cursor
counter = 0;
cursor.forEach(function(doc) {
// computations
var c1, c2, c3, c4, Field8;
c1 = 10 + (0.03*doc.Field3);
c2 = (doc.Field2 == 1) ? 1: 0.03;
c3 = 7 - (doc.Field5.match(new RegExp(".", "g")) || []).length;
c4 = (doc.Field2 == 1) ? Math.pow(doc.Field, -0.6) : 1;
Field8 = c1*c2*c3*c4;
bulkUpdateOps.find({ "_id": doc._id }).updateOne({
"$set": { "Field8": Field8 }
});
if (counter % 500 == 0) {
bulkUpdateOps.execute();
bulkUpdateOps = db.collection1.initializeUnorderedBulkOp();
}
})
if (counter % 500 != 0) { bulkUpdateOps.execute(); }