MongoDb -将类型从Int改为Double



我们有一个像这样的集合:

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

现在,一些"v"是整型,一些是双精度。我想把它们都改成double。

我已经尝试了一些事情,但没有工作(v是一个int32这个记录,我想把它改为双精度):

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

默认情况下,所有"number "在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类型。

那么用Type 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 }

这是在shell中使用NumberInt()函数的"第三"插入。因此,来自驱动程序的函数和其他序列化可以设置此特定的BSON类型。

对于BSON Type 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();

这个操作分三步"批量"执行:

  1. 将值重新转换为一个新字段作为"double"
  2. 删除不需要的类型
  3. 的旧字段
  4. 将新字段重命名为旧字段名

这是必需的,因为BSON类型信息一旦创建就"粘"在字段元素上。因此,为了"重新转换",您需要完全删除旧数据,其中包括原始字段分配。

所以这应该解释了如何在你的文档中"检测"one_answers"重新转换"不需要的类型

最新更新