MongoDb-将类型从Int更改为Double

MongoDb-将类型从Int更改为Double,mongodb,casting,Mongodb,Casting,我们有一个类似以下内容的集合: { "_id" : "10571:6", "v" : 261355, "ts" : 4.88387e+008 } 现在,有些“v”是整数,有些是双数。我想把它们都换成双打 我尝试了一些方法,但没有任何效果(对于此记录,v是int32,我想将其更改为双精度): 我尝试过的事情: x.v = x.v * 1.1 / 1.1; x.v = parseFloat (new String(x.v)); 但我无法将其保存为双精度…默认情况下,所有“

我们有一个类似以下内容的集合:

{
    "_id" : "10571:6",
    "v" : 261355,
    "ts" : 4.88387e+008
}
现在,有些“v”是整数,有些是双数。我想把它们都换成双打

我尝试了一些方法,但没有任何效果(对于此记录,v是int32,我想将其更改为双精度):

我尝试过的事情:

x.v = x.v * 1.1 / 1.1;
x.v = parseFloat (new String(x.v));
但我无法将其保存为双精度…

默认情况下,所有“数字”在MongoDB中都存储为“双精度”,除非通常强制转换为overwise

采取以下样本:

db.sample.insert({“a”:1})
db.sample.insert({“a”:NumberLong(1)})
db.sample.insert({“a”:numberprint(1)})
db.sample.insert({“a”:1.223})
这将产生如下集合:

{
    "_id" : "10571:6",
    "v" : 261355,
    "ts" : 4.88387e+008
}
{u id:ObjectId(“559bb1b4a23c8a3da73e0f76”),“a”:1}
{“_id”:ObjectId(“559BB1BBBA23C8A3DA73E0F77”),“a”:NumberLong(1)}
{“_id”:ObjectId(“559bb29aa23c8a3da73e0f79”),“a”:1}
{u id:ObjectId(“559bb30fa23c8a3da73e0f7a”),“a”:1.223}
尽管构造器函数不同,但请注意其中的几个数据点看起来几乎相同。MongoDB外壳本身并不总是清楚地区分它们,但是有一种方法可以区分它们

当然还有查询操作符,它允许选择BSON类型

因此,使用类型1(即“双精度”)进行测试:

>db.sample.find({“a”:{“$type”:1})
{“_id”:ObjectId(“559bb1b4a23c8a3da73e0f76”),“a”:1}
{u id:ObjectId(“559bb30fa23c8a3da73e0f7a”),“a”:1.223}
您可以看到,第一次插入和最后一次插入都被选中,但其他两次当然不会被选中

现在测试BSON类型16,它是一个32位整数

>db.sample.find({“a”:{“$type”:16})
{“_id”:ObjectId(“559bb29aa23c8a3da73e0f79”),“a”:1}
这是在shell中使用
numberrint()
函数的“第三次”插入。因此,驱动程序中的函数和其他序列化可以设置此特定BSON类型

对于BSON类型18,它是64位整数

>db.sample.find({“a”:{“$type”:18})
{“_id”:ObjectId(“559BB1BBBA23C8A3DA73E0F77”),“a”:NumberLong(1)}
通过
NumberLong()
进行的“第二次”插入

如果你想“剔除”那些“不是替身”的东西,那么你应该:

db.sample.find({“$or”:[{“a”:{“$type”:16}},{“a”:{“$type”:18}}]})
这是除了“double”本身之外唯一有效的数字类型

因此,要在您的收藏中“转换”这些,您可以像这样“批量”处理:

{
    "_id" : "10571:6",
    "v" : 261355,
    "ts" : 4.88387e+008
}
var bulk=db.sample.initializeUnderedBulkop(),
计数=0;
db.sample.find({
“$or”:[
{“a”:{“$type”:16},
{“a”:{“$type”:18}
]
}).forEach(功能(文档){
bulk.find({“\u id”:doc.\u id})
.updateOne({
“$set”:{“b”:doc.a.valueOf()},
“$unset”:{“a”:1}
});
bulk.find({“\u id”:doc.\u id})
.updateOne({“$rename”:{“b”:“a}});
计数++;
如果(计数%1000==0){
bulk.execute()
bulk=db.sample.initializeUnderedBulkop();
}
})
如果(计数%1000!=0)bulk.execute();
该操作分为三个“批量”步骤:

  • 将值作为“双精度”重新转换为新字段
  • 删除不需要类型的旧字段
  • 将新字段重命名为旧字段名
  • 这是必要的,因为一旦创建了字段元素,BSON类型信息就会“粘滞”到字段元素。因此,为了“重播”,您需要完全删除包含原始字段分配的旧数据


    因此,这应该解释如何在文档中“检测”并“重新转换”不需要的类型。

    在mongo shell中,所有数字都作为浮点值。可能重复@chridam我知道我可以将其转换为int,但我想将其转换为double:)谢谢!我试试看。我想删除并插入我的文档,但我希望有一个更简单的方法。@Carra只需移动和重命名字段,就可以更快地完成。特别是使用如图所示的批量操作,请求最多会以单数响应批量发送。删除文档必然会导致重新分配并减慢I/O速度。第二个初始值eunorderedbulkop键入错误