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