如何更改Mongo文档中嵌套字段的数据类型? [英] How to change datatype of nested field in Mongo document?

查看:145
本文介绍了如何更改Mongo文档中嵌套字段的数据类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Mongo结构如下,

My Mongo structure as below,

"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"
        } 
    ]

上面的文档中的topProcesses.cpuUtilizationPercent现在是字符串,我想将topProcesses.cpuUtilizationPercent数据类型更改为Float.为此,我在下面尝试了一下,但没有成功

Now in above documents topProcesses.cpuUtilizationPercent is in string and I wanted to change topProcesses.cpuUtilizationPercent data type to Float. For this I tried below but it did not work

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

任何人都可以帮助如何将字符串更改为在嵌套的Mongo文档中浮动

Can any one help how to changed string to float in nested Mongo documents

推荐答案

您这样做的方式正确,但是您没有在.update()的查询部分中包含要匹配的数组元素:

You are doing this the right way but you did not include the array element to match in the query portion of the .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)
             }
         }
      );
  }
})

因此,您需要匹配数组中的某些内容,以便使用位置$ 运算符起作用.

So you need to match something in the array in order for the positional $ operator to have any effect.

您还可能只在符号中使用了索引"值,因为无论如何您都是在循环中生成该值:

You also could have just used the "index" value in the notation, since you are producing that in a loop 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
      );
  }
})

仅使用匹配索引,在没有数组元素唯一标识符的情况下非常方便.

Which just uses the matching index and is handy where there is no unique identifier of the array element.

还请注意,由于这是处理现有文档的方式的性质,因此"upsert"或"multi"选项均不适用于此处.

Also note that neither the "upsert" or "multi" options should apply here due to the nature of how this is processes existing documents.

作为对此的后记"笔记,值得考虑的是2.6及更高版本的MongoDB的Bulk Operations API.使用这些API方法,可以大大减少客户端应用程序和数据库之间的网络流量.明显的改进是总体速度:

Just as a "postscript" note to this, it is also worthwhile to consider the Bulk Operations API of MongoDB in versions from 2.6 and greater. Using these API methods you can significantly reduce the amount of network traffic between your client application and the database. The obvious improvement here is in the overall speed:

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

这基本上将发送到服务器的操作语句数量减少为每1000个排队的操作仅发送一次.您可以使用该数字以及事物的分组方式,但是它将以相对安全的方式显着提高速度.

This basically reduces the amount of operations statements sent to the sever to only sending once every 1000 queued operations. You can play with that number and how things are grouped but it will give a significant increase in speed in a relatively safe way.

这篇关于如何更改Mongo文档中嵌套字段的数据类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆