Tùy thuộc vào nhu cầu ứng dụng của bạn, bạn có thể sử dụng khung tổng hợp để tính điểm và sử dụng BulWrite ()
để cập nhật bộ sưu tập của bạn. Hãy xem xét ví dụ sau sử dụng mã <> $ dự án
bước đường ống dẫn như một sự nhàn rỗi cho các phép tính điểm số với các toán tử số học.
Vì logic để tính toán C3
trong câu hỏi của bạn là nhận được một số từ 1
thành 7
bằng chính xác 7 - số điểm (.)
, cách tiếp cận khả thi duy nhất mà tôi có thể nghĩ đến là lưu trữ thêm một trường giữ giá trị này trước khi thực hiện tổng hợp. Vì vậy, bước đầu tiên của bạn sẽ là tạo trường bổ sung đó và bạn có thể tiếp tục bằng cách sử dụng BulWrite ()
như sau:
Bước 1:Sửa đổi giản đồ để chứa thêm daysInWeek
lĩnh vực
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); }
Lý tưởng nhất là thao tác trên cũng có thể phù hợp với việc tính toán các hằng số khác trong câu hỏi của bạn và do đó tạo ra Field8
kết quả là. Tuy nhiên, tôi tin rằng các phép tính như thế này nên được thực hiện trên máy khách và để MongoDB làm những gì nó hoạt động tốt nhất trên máy chủ.
Bước 2:Sử dụng tổng hợp để thêm Field8
lĩnh vực
Đã tạo trường bổ sung đó daysInWeek
sau đó, bạn có thể xây dựng một đường dẫn tổng hợp dự báo các biến mới bằng cách sử dụng nhóm thuần tập toán tử số học
để thực hiện tính toán (một lần nữa, bạn nên thực hiện các phép tính như vậy trên lớp ứng dụng). Phép chiếu cuối cùng sẽ là sản phẩm của các trường được tính toán mà sau đó bạn có thể sử dụng con trỏ kết quả tổng hợp để lặp lại và thêm Field8
vào bộ sưu tập với mỗi tài liệu:
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); }
Đối với MongoDB > =2.6
và <=3.0
, sử dụng API hoạt động hàng loạt
nơi bạn cần lặp lại bộ sưu tập bằng cách sử dụng của con trỏ forEach ()
phương pháp, cập nhật từng tài liệu trong bộ sưu tập.
Một số toán tử số học từ đường ống tổng hợp ở trên không khả dụng trong MongoDB > =2.6
và <=3.0
vì vậy bạn sẽ cần thực hiện các phép tính trong forEach ()
sự lặp lại.
Sử dụng API hàng loạt để giảm yêu cầu ghi của máy chủ bằng cách nhóm từng bản cập nhật hàng loạt và chỉ gửi đến máy chủ một lần trong mỗi 500 tài liệu trong bộ sưu tập để xử lý:
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(); }