2014-12-16 16 views
7

My Mongo cấu trúc như dưới đây,Làm thế nào để thay đổi kiểu dữ liệu của trường lồng nhau trong tài liệu Mongo?

"topProcesses" : [ 
     { 
      "cpuUtilizationPercent" : "0.0", 
      "processId" : "1", 
      "memoryUtilizationPercent" : "0.1", 
      "command" : "init", 
      "user" : "root" 
     }, 
     { 
      "cpuUtilizationPercent" : "0.0", 
      "processId" : "2", 
      "memoryUtilizationPercent" : "0.0", 
      "command" : "kthreadd", 
      "user" : "root" 
     }, 
     { 
      "cpuUtilizationPercent" : "0.0", 
      "processId" : "3", 
      "memoryUtilizationPercent" : "0.0", 
      "command" : "ksoftirqd/0", 
      "user" : "root" 
     }, 
     { 
      "cpuUtilizationPercent" : "0.0", 
      "processId" : "5", 
      "memoryUtilizationPercent" : "0.0", 
      "command" : "kworker/0:+", 
      "user" : "root" 
     }, 
     { 
      "cpuUtilizationPercent" : "0.0", 
      "processId" : "6", 
      "memoryUtilizationPercent" : "0.0", 
      "command" : "kworker/u3+", 
      "user" : "root" 
     }, 
     { 
      "cpuUtilizationPercent" : "0.0", 
      "processId" : "8", 
      "memoryUtilizationPercent" : "0.0", 
      "command" : "rcu_sched", 
      "user" : "root" 
     } 
    ] 

Bây giờ trong các văn bản nêu trên topProcesses.cpuUtilizationPercent là trong chuỗi và tôi muốn thay đổi topProcesses.cpuUtilizationPercent kiểu dữ liệu để Float. Đối với điều này tôi đã cố gắng dưới đây nhưng nó đã không làm việc

db.collectionName.find({ 
    "topProcesses":{"$exists":true}}).forEach(function(data){ 
    for(var ii=0;ii<data.topProcesses.length;ii++){ 
    db.collectionName.update({_id: data._id},{$set:{"topProcesses.$.cpuUtilizationPercent":parseFloat(data.topProcesses[ii].cpuUtilizationPercent)}},false,true); 
    } 
}) 

thể bất kỳ một sự giúp đỡ làm thế nào để thay đổi chuỗi nổi trong các văn bản Mongo lồng nhau

Trả lời

7

Bạn đang làm điều này một cách đúng đắn nhưng bạn đã không bao gồm các phần tử mảng để phù hợ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 phải phù hợp một cái gì đó trong mảng theo thứ tự cho các nhà điều hành positional $ để có hiệu lực.

Bạn cũng có thể chỉ cần sử dụng các "chỉ số" giá trị trong các ký hiệu, kể từ khi bạn đang sản xuất mà trong một vòng lặp anyway:

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 
    ); 
    } 
}) 

Mà chỉ cần sử dụng các chỉ số phù hợp và rất thuận tiện mà không có độc đáo định danh của phần tử mảng.

Cũng lưu ý rằng không phải tùy chọn "upsert" hoặc "đa" nên áp dụng ở đây do tính chất của cách xử lý tài liệu hiện có.


Cũng giống như lưu ý "postscript" cho điều này, bạn cũng nên xem xét API hoạt động hàng loạt của MongoDB trong phiên bản từ 2.6 trở lên. Sử dụng các phương thức API này, bạn có thể giảm đáng kể lưu lượng mạng giữa ứng dụng khách và cơ sở dữ liệu của bạn. 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 báo cáo hoạt động được gửi tới máy chủ để chỉ gửi một lần 1000 hoạt động xếp hàng. Bạn có thể chơi với con số đó và mọi thứ được nhóm lại như thế nào nhưng nó sẽ làm tăng đáng kể tốc độ một cách tương đối an toàn.

-1

bạn có thể sử dụng dưới đây truy vấn để cập nhật datatype của topProcesses.cpuUtilizationPercent từ chuỗi nổi

db.db.find({"topProcesses.cpuUtilizationPercent" : {$exists : true}}). 
forEach(function(obj) 
{ obj.topProcesses.cpuUtilizationPercent = new ISODate(obj.topProcesses.cpuUtilizationPercent); 
db.db.save(obj); }); 
Các vấn đề liên quan