MongoDb - 将类型从Int更改为Double [英] MongoDb - Change type from Int to Double

查看:1874
本文介绍了MongoDb - 将类型从Int更改为Double的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个类似这样的集合:

  {
_id:10571:6 ,
v:261355,
ts:4.88387e + 008
}

现在,一些v是int,有些是双精度。



我尝试了一些东西,但没有什么工作(v是一个int32的记录,我想把它改为一个double):

  db.getCollection('VehicleLastValues')
.find

{_id:10572:6}

.forEach

function(x)
{
temp = xv * 1.0;
db.getCollection('VehicleLastValues')。save(x);
}}

我尝试的东西:

  xv = xv * 1.1 / 1.1; 
xv = parseFloat (new String(xv));

但我无法将其保存为double ...

解决方案

默认情况下,所有数字都存储为double



采取以下示例:

  db.sample.insert({a:1})
db.sample.insert({a:NumberLong(1)})
db.sample.insert ({a:NumberInt(1)})
db.sample.insert({a:1.223})

这将产生如下集合:

  {_id :ObjectId(559bb1b4a23c8a3da73e0f76),a:1} 
{_id:ObjectId(559bb1bba23c8a3da73e0f77),a:NumberLong(1)}
{_id:ObjectId (559bb29aa23c8a3da73e0f79),a:1}
{_id:ObjectId(559bb30fa23c8a3da73e0f7a),a:1.223}

尽管不同的构造函数注意了几个数据点看起来是否一样。



当然还有 $ type 查询运算符选择BSON类型。



因此使用类型1测试 - 这是double:

 > db.sample.find({a:{$ type:1}})
{_id:ObjectId(559bb1b4a23c8a3da73e0f76),a:1}
{_id :ObjectId(559bb30fa23c8a3da73e0f7a),a:1.223}



现在测试BSON类型16 - 这是一个32位整数

 > db.sample.find({a:{$ type:16}})
{_id:ObjectId(559bb29aa23c8a3da73e0f79),a:1}
< c $ c>

这是第三个插入,它使用 NumberInt()壳。因此,从您的驱动程序的功能和其他序列化可以设置此特定的BSON类型。



而对于BSON类型18 - 这是64位整数

 > db.sample.find({a:{$ type:18}})
{_id:ObjectId(559bb1bba23c8a3da73e0f77),a:NumberLong(1)}

通过 NumberLong()



如果你想清除那些不是双重的东西,那么你可以这样做:



< pre=lang-js prettyprint-override> db.sample.find({$或:[{a:{$ type:16}},{ :{$ type:18}}]})



因此,为了转换您的集合中的这些,您可以这样处理批量:

  var bulk = db.sample.initializeUnorderedBulkOp(),
count = 0;
db.sample.find({
$或:[
{a:{$ type:16}},
{a:{ $ type:18}}
]
})forEach(function(doc){
bulk.find({_id:doc._id})
。 updateOne({
$ set:{b:doc.a.valueOf()},
$ unset:{a:1}
});
bulk.find({_id:doc._id})
.updateOne({$ rename:{b:a}});
count ++;
if(count%1000 == 0){
bulk.execute()
bulk = db.sample.initializeUnOrderedBulkOp();
}
})
if(count%1000!= 0)bulk.execute();这是通过三个步骤批量执行:




  1. 将值重新转换为新字段为double

  2. 删除不需要的类型的旧字段

  3. 将新字段重命名为旧字段名称

这是必要因为BSON类型信息对于一旦创建的字段元素是粘性的。因此,为了重新生成,您需要完全删除包含原始字段分配的旧数据。



因此,应该解释如何检测在您的文档中重新投放不需要的类型。


We have a collection that looks like this:

{
    "_id" : "10571:6",
    "v" : 261355,
    "ts" : 4.88387e+008
}

Now, some of the "v" are ints, some are doubles. I want to change them all to doubles.

I've tried a few things but nothing works (v is an int32 for this record, I want to change it to a double):

db.getCollection('VehicleLastValues')
.find
(

    {_id : "10572:6"}
)
.forEach
(
function (x)
{
    temp = x.v * 1.0;
    db.getCollection('VehicleLastValues').save(x);
}}

Things I've tried:

x.v = x.v * 1.1 / 1.1;
x.v = parseFloat (new String(x.v));

But I can't get it to be saved as a double...

解决方案

By default all "numbers" are stored as "double" in MongoDB unless generally cast overwise.

Take the following samples:

db.sample.insert({ "a": 1 })
db.sample.insert({ "a": NumberLong(1) })
db.sample.insert({ "a": NumberInt(1) })
db.sample.insert({ "a": 1.223 })

This yields a collection like this:

{ "_id" : ObjectId("559bb1b4a23c8a3da73e0f76"), "a" : 1 }
{ "_id" : ObjectId("559bb1bba23c8a3da73e0f77"), "a" : NumberLong(1) }
{ "_id" : ObjectId("559bb29aa23c8a3da73e0f79"), "a" : 1 }
{ "_id" : ObjectId("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 }

Despite the different constructor functions note how several of the data points there look much the same. The MongoDB shell itself doesn't always clearly distinquish between them, but there is a way you can tell.

There is of course the $type query operator, which allows selection of BSON Types.

So testing this with Type 1 - Which is "double":

> db.sample.find({ "a": { "$type": 1 } })
{ "_id" : ObjectId("559bb1b4a23c8a3da73e0f76"), "a" : 1 }
{ "_id" : ObjectId("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 }

You see that both the first insert and the last are selected, but of course not the other two.

So now test for BSON Type 16 - which is a 32-bit integer

> db.sample.find({ "a": { "$type": 16 } })
{ "_id" : ObjectId("559bb29aa23c8a3da73e0f79"), "a" : 1 }

That was the "third" insertion which used the NumberInt() function in the shell. So that function and other serialization from your driver can set this specific BSON type.

And for the BSON Type 18 - which is 64-bit integer

> db.sample.find({ "a": { "$type": 18 } })
{ "_id" : ObjectId("559bb1bba23c8a3da73e0f77"), "a" : NumberLong(1) }

The "second" insertion which was contructed via NumberLong().

If you wanted to "weed out" things that were "not a double" then you would do:

db.sample.find({ "$or": [{ "a": { "$type": 16 } },{ "a": { "$type": 18 } }]})

Which are the only other valid numeric types other than "double" itself.

So to "convert" these in your collection, you can "Bulk" process like this:

var bulk = db.sample.initializeUnorderedBulkOp(),
    count = 0;
db.sample.find({ 
    "$or": [
        { "a": { "$type": 16 } },
        { "a": { "$type": 18 } }
    ]
}).forEach(function(doc) {
    bulk.find({ "_id": doc._id })
        .updateOne({ 
            "$set": { "b": doc.a.valueOf() } ,
            "$unset": { "a": 1 } 
        });
    bulk.find({ "_id": doc._id })
        .updateOne({ "$rename": { "b": "a" } });
    count++;
    if ( count % 1000 == 0 ) {
        bulk.execute()
        bulk = db.sample.initializeUnOrderedBulkOp();
    }
})
if ( count % 1000 != 0 ) bulk.execute();

What that does is performed in three steps "in bulk":

  1. Re-cast the value to a new field as a "double"
  2. Remove the old field with the unwanted type
  3. Rename the new field to the old field name

This is necessary since the BSON type information is "sticky" to the field element once created. So in order to "re-cast" you need to completely remove the old data which includes the original field assignment.

So that should explain how to "detect" and also "re-cast" unwanted types in your documents.

这篇关于MongoDb - 将类型从Int更改为Double的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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