我们有一个如下所示的集合:
{
"_id" : "10571:6",
"v" : 261355,
"ts" : 4.88387e+008
}
现在,有些" v"是整数,有些是双打。我想将它们全部改为双打。
我尝试了一些事情,但没有任何作用(v是此记录的int32,我想将其更改为double):
db.getCollection('VehicleLastValues')
.find
(
{_id : "10572:6"}
)
.forEach
(
function (x)
{
temp = x.v * 1.0;
db.getCollection('VehicleLastValues').save(x);
}}
我尝试的事情:
x.v = x.v * 1.1 / 1.1;
x.v = parseFloat (new String(x.v));
但我无法将其保存为双人......
答案 0 :(得分:9)
默认情况下,所有“数字”在MongoDB中都存储为“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 }
尽管构造函数不同,但请注意其中的几个数据点看起来大致相同。 MongoDB shell本身并不总是明确区分它们,但有一种方法可以告诉你。
当然有$type
查询运算符,它允许选择BSON类型。
因此使用类型1进行测试 - 这是“双重”:
> db.sample.find({ "a": { "$type": 1 } })
{ "_id" : ObjectId("559bb1b4a23c8a3da73e0f76"), "a" : 1 }
{ "_id" : ObjectId("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 }
您会看到第一个插入和最后一个插入都被选中,但当然不是其他两个插入。
现在测试BSON Type 16 - 这是一个32位整数
> db.sample.find({ "a": { "$type": 16 } })
{ "_id" : ObjectId("559bb29aa23c8a3da73e0f79"), "a" : 1 }
这是在shell中使用NumberInt()
函数的“第三个”插入。因此,驱动程序中的函数和其他序列化可以设置此特定的BSON类型。
对于BSON类型18 - 这是64位整数
> db.sample.find({ "a": { "$type": 18 } })
{ "_id" : ObjectId("559bb1bba23c8a3da73e0f77"), "a" : NumberLong(1) }
通过NumberLong()
构建的“第二个”插入。
如果你想“清除”那些“不是双重”的东西,那么你会这样做:
db.sample.find({ "$or": [{ "a": { "$type": 16 } },{ "a": { "$type": 18 } }]})
除了“double”本身之外,其他唯一有效的数字类型。
所以要在你的收藏中“转换”这些,你可以像这样“批量”处理:
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();
通过“批量”三个步骤执行的操作:
这是必要,因为BSON类型信息在创建后对字段元素是“粘性的”。因此,为了“重新投射”,您需要完全删除包含原始字段分配的旧数据。
这应该解释如何在文档中“检测”并“重新投射”不需要的类型。