Bạn đang làm điều này đúng cách nhưng bạn đã không bao gồm phần tử mảng để khớp trong phần truy vấn của .update ()
:
db.collectionName.find({
"topProcesses":{"$exists":true}}).forEach(function(data){
for(var ii=0;ii<data.topProcesses.length;ii++) {
db.collectionName.update(
{
"_id": data._id,
"topProcesses.processId": data.topProcesses[ii].processId // corrected
},
{
"$set": {
"topProcesses.$.cpuUtilizationPercent":
parseFloat(data.topProcesses[ii].cpuUtilizationPercent)
}
}
);
}
})
Vì vậy, bạn cần so khớp một thứ gì đó trong mảng để tạo mã vị trí <> $ toán tử để có bất kỳ ảnh hưởng nào.
Bạn cũng có thể vừa sử dụng giá trị "chỉ mục" trong ký hiệu, vì dù sao thì bạn cũng đang tạo ra giá trị đó trong một vòng lặp:
db.collectionName.find({
"topProcesses":{"$exists":true}}).forEach(function(data){
for(var ii=0;ii<data.topProcesses.length;ii++) {
var updoc = {
"$set": {}
};
var myKey = "topProcesses." + ii + ".cpuUtilizationPercent";
updoc["$set"][myKey] = parseFloat(data.topProcesses[ii].cpuUtilizationPercent);
db.collectionName.update(
{
"_id": data._id
},
updoc
);
}
})
Điều này chỉ sử dụng chỉ mục phù hợp và tiện dụng khi không có số nhận dạng duy nhất của phần tử mảng.
Cũng xin lưu ý rằng các tùy chọn "nâng cấp" hoặc "đa" sẽ không được áp dụng ở đây do bản chất của cách thức này xử lý các tài liệu hiện có.
Cũng giống như một lưu ý "tái bút" cho điều này, cũng nên xem xét API hoạt động hàng loạt của MongoDB trong các phiên bản từ 2.6 trở lên. Sử dụng các phương pháp API này, bạn có thể giảm đáng kể lượng lưu lượng mạng giữa ứng dụng khách và cơ sở dữ liệu. Sự cải thiện rõ ràng ở đây là tốc độ tổng thể:
var bulk = db.collectionName.initializeOrderedBulkOp();
var counter = 0;
db.collectionName.find({
"topProcesses":{"$exists":true}}
).forEach(function(data){
for(var ii=0;ii<data.topProcesses.length;ii++) {
var updoc = {
"$set": {}
};
var myKey = "topProcesses." + ii + ".cpuUtilizationPercent";
updoc["$set"][myKey] = parseFloat(data.topProcesses[ii].cpuUtilizationPercent);
// queue the update
bulk.find({ "_id": data._id }).update(updoc);
counter++;
// Drain and re-initialize every 1000 update statements
if ( counter % 1000 == 0 ) {
bulk.execute();
bulk = db.collectionName.initializeOrderedBulkOp();
}
}
})
// Add the rest in the queue
if ( counter % 1000 != 0 )
bulk.execute();
Điều này về cơ bản làm giảm số lượng các câu lệnh hoạt động được gửi đến máy chủ để chỉ gửi một lần sau mỗi 1000 hoạt động được xếp hàng đợi. Bạn có thể chơi với con số đó và cách mọi thứ được nhóm lại nhưng nó sẽ giúp tăng tốc độ đáng kể theo cách tương đối an toàn.