MongoDB:如何更改字段的类型?

时间:2011-02-11 19:18:37

标签: mongodb

Stackoverflow中已经存在一个问题,与我的问题非常相似。 问题是这些问题的答案是针对Java驱动程序,我试图在shell中进行。

我这样做......

db.meta.update({'fields.properties.default': { $type : 1 }}, {'fields.properties.default': { $type : 2 }})

这不起作用!

14 个答案:

答案 0 :(得分:185)

更改数据$type的唯一方法是对数据类型正确的数据执行更新。

在这种情况下,您似乎正在尝试更改$type from 1 (double) to 2 (string)

只需从数据库加载文档,执行强制转换(new String(x)),然后再次保存文档。

如果您需要以编程方式完全从shell执行此操作,则可以使用find(...).forEach(function(x) {})语法。


回应下面的第二条评论。将字段bad从数字更改为集合foo中的字符串。

db.foo.find( { 'bad' : { $type : 1 } } ).forEach( function (x) {   
  x.bad = new String(x.bad); // convert field to string
  db.foo.save(x);
});

答案 1 :(得分:148)

将字符串字段转换为整数:

db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) { 
    obj.field-name = new NumberInt(obj.field-name);
    db.db-name.save(obj);
});

将整数字段转换为字符串:

db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) {
    obj.field-name = "" + obj.field-name;
    db.db-name.save(obj);
});

答案 2 :(得分:35)

用于字符串到int的转换。

db.my_collection.find().forEach( function(obj) {
    obj.my_value= new NumberInt(obj.my_value);
    db.my_collection.save(obj);
});

用于字符串到双重转换。

    obj.my_value= parseInt(obj.my_value, 10);

浮动:

    obj.my_value= parseFloat(obj.my_value);

答案 3 :(得分:20)

db.coll.find().forEach(function(data) {
    db.coll.update({_id:data._id},{$set:{myfield:parseInt(data.myfield)}});
})

答案 4 :(得分:4)

要在没有创建数组的情况下将int32转换为mongo中的字符串只需在数字中添加“”< - strong>: - )

db.foo.find( { 'mynum' : { $type : 16 } } ).forEach( function (x) {   
  x.mynum = x.mynum + ""; // convert int32 to string
  db.foo.save(x);
});

答案 5 :(得分:4)

到目前为止,所有答案都使用某些版本的forEach,在客户端迭代所有集合元素。

但是,您可以通过使用聚合管道和$out stage来使用MongoDB的服务器端处理:

  

$ out阶段以原子方式替换现有集合   新的结果集合。

示例:

db.documents.aggregate([
         {
            $project: {
               _id: 1,
               numberField: { $substr: ['$numberField', 0, -1] },
               otherField: 1,
               differentField: 1,
               anotherfield: 1,
               needolistAllFieldsHere: 1
            },
         },
         {
            $out: 'documents',
         },
      ]);

答案 6 :(得分:3)

要将字符串类型的字段转换为日期字段,您需要使用 find() forEach() 方法返回的光标>方法,在循环中将字段转换为Date对象,然后使用 $set 运算符更新字段。

利用 Bulk API 进行批量更新,从而提供更好的性能,因为您将以1000个批量向服务器发送操作,从而为您提供更好的性能没有向服务器发送每个请求,每1000个请求只发送一次。

以下演示了此方法,第一个示例使用MongoDB版本>= 2.6 and < 3.2中提供的批量API。它更新所有 通过将所有created_at字段更改为日期字段来收集集合中的文档:

var bulk = db.collection.initializeUnorderedBulkOp(),
    counter = 0;

db.collection.find({"created_at": {"$exists": true, "$type": 2 }}).forEach(function (doc) {
    var newDate = new Date(doc.created_at);
    bulk.find({ "_id": doc._id }).updateOne({ 
        "$set": { "created_at": newDate}
    });

    counter++;
    if (counter % 1000 == 0) {
        bulk.execute(); // Execute per 1000 operations and re-initialize every 1000 update statements
        bulk = db.collection.initializeUnorderedBulkOp();
    }
})
// Clean up remaining operations in queue
if (counter % 1000 != 0) { bulk.execute(); }

下一个示例适用于自 deprecated the Bulk API 以来的新MongoDB版本3.2,并使用 bulkWrite()

var bulkOps = [];

db.collection.find({"created_at": {"$exists": true, "$type": 2 }}).forEach(function (doc) { 
    var newDate = new Date(doc.created_at);
    bulkOps.push(         
        { 
            "updateOne": { 
                "filter": { "_id": doc._id } ,              
                "update": { "$set": { "created_at": newDate } } 
            }         
        }           
    );     
})

db.collection.bulkWrite(bulkOps, { "ordered": true });

答案 7 :(得分:3)

真正帮助我改变MondoDB中对象类型的真正原因就在于这个简单的行,可能在此之前提到过......:

      a    b    c                  d
1  0.60 0.27 0.14               0.13
2  0.48 0.32 0.21                0.2
3  0.42 0.24 0.35               0.23
4  0.28 0.33 0.41               0.26
5  0.52 0.28 0.22                0.2
6  0.34 0.30 0.37               0.29
7  0.38 0.28 0.35               0.27
8  0.34 0.28 0.40               0.26
9  0.53 0.26 0.22               0.21
10 0.17 0.27 0.58               0.15
11 0.34 0.35 0.33               0.31
12 0.19 0.27 0.56               0.17
13 0.56 0.29 0.17               0.15
14 0.55 0.28 0.19               0.17
15 0.29 0.24 0.48               0.23
16 0.23 0.31 0.47               0.22
17 0.40 0.32 0.28               0.33  #From here til the end it's wrong!
18 0.50 0.27 0.24               0.19
19 0.45 0.28 0.27               0.28
20 0.68 0.26 0.05               0.24
21 0.40 0.32 0.28               0.28
22 0.23 0.26 0.50               0.26
23 0.46 0.33 0.20               0.25
24 0.46 0.24 0.28               0.27
25 0.44 0.24 0.31                0.3
26 0.46 0.26 0.27               0.21
27 0.30 0.29 0.40               0.24
28 0.45 0.20 0.34 0.0599999999999999
29 0.53 0.27 0.20               0.33
30 0.33 0.34 0.33               0.06
31 0.20 0.26 0.55               0.15
32 0.65 0.29 0.06               0.27
33 0.45 0.24 0.32               0.17
34 0.30 0.26 0.45               0.15
35 0.20 0.36 0.45               0.17
36 0.38 0.16 0.38               0.24

用户是我的集合,age是具有字符串而不是整数(int32)的对象。

答案 8 :(得分:1)

我需要更改集合中多个字段的数据类型,因此我使用以下内容在文档集合中进行多个数据类型更改。回答一个旧问题但可能对其他人有所帮助。

db.mycoll.find().forEach(function(obj) { 

    if (obj.hasOwnProperty('phone')) {
        obj.phone = "" + obj.phone;  // int or longint to string
    }

    if (obj.hasOwnProperty('field-name')) {
     obj.field-name = new NumberInt(obj.field-name); //string to integer
    }

    if (obj.hasOwnProperty('cdate')) {
        obj.cdate = new ISODate(obj.cdate); //string to Date
    }

    db.mycoll.save(obj); 
});

答案 9 :(得分:1)

You can easily convert the string data type to numerical data type.
Don't forget to change collectionName & FieldName.
for ex : CollectionNmae : Users & FieldName : Contactno.

尝试此查询..

db.collectionName.find().forEach( function (x) {
x.FieldName = parseInt(x.FieldName);
db.collectionName.save(x);
});

答案 10 :(得分:1)

Mongo 4.2开始,db.collection.update()可以接受聚合管道,最后允许根据其自身值更新字段:

// { a: "45", b: "x" }
// { a:  53,  b: "y" }
db.collection.update(
  { a : { $type: 1 } },
  [{ $set: { a: { $toString: "$a" } } }],
  { multi: true }
)
// { a: "45", b: "x" }
// { a: "53", b: "y" }
  • 第一部分{ a : { $type: 1 } }是匹配查询:

    • 它过滤要更新的文档。
    • 在这种情况下,由于我们希望将"a"的值转换为double值时将其转换为字符串,因此它将匹配"a"类型为1(double)的元素。 / li>
    • table提供了代表不同可能类型的代码。
  • 第二部分[{ $set: { a: { $toString: "$a" } } }]是更新聚合管道:

    • 请注意方括号,表明该更新查询使用了聚合管道。
    • $set是新的聚合运算符(Mongo 4.2),在这种情况下,它会修改字段。
    • 这可以简单地理解为"$set""a""$a"转换后的"$toString"的值。
    • 这里真正的新功能是,Mongo 4.2能够在更新文档时引用文档本身:"a"的新值基于"$a"的现有值。
    • li>
    • 还请注意"$toString",这是Mongo 4.0中引入的新聚合运算符。
  • 不要忘记{ multi: true },否则只会更新第一个匹配的文档。


如果您的转换不是从双精度转换为字符串,则可以在Mongo 4.0中引入的不同转换运算符之间进行选择,例如$toBool$toInt,...

如果没有用于目标类型的专用转换器,则可以将{ $toString: "$a" }替换为$convert操作:{ $convert: { input: "$a", to: 2 } },其中to的值可以是在此table中找到:

db.collection.update(
  { a : { $type: 1 } },
  [{ $set: { a: { $convert: { input: "$a", to: 2 } } } }],
  { multi: true }
)

答案 11 :(得分:0)

我在mongodb控制台中使用此脚本进行字符串浮动转换...

db.documents.find({ 'fwtweaeeba' : {$exists : true}}).forEach( function(obj) { 
        obj.fwtweaeeba = parseFloat( obj.fwtweaeeba ); 
        db.documents.save(obj); } );    

db.documents.find({ 'versions.0.content.fwtweaeeba' : {$exists : true}}).forEach( function(obj) { 
        obj.versions[0].content.fwtweaeeba = parseFloat( obj.versions[0].content.fwtweaeeba ); 
        db.documents.save(obj); } );

db.documents.find({ 'versions.1.content.fwtweaeeba' : {$exists : true}}).forEach( function(obj) { 
        obj.versions[1].content.fwtweaeeba = parseFloat( obj.versions[1].content.fwtweaeeba );  
        db.documents.save(obj); } );

db.documents.find({ 'versions.2.content.fwtweaeeba' : {$exists : true}}).forEach( function(obj) { 
        obj.versions[2].content.fwtweaeeba = parseFloat( obj.versions[2].content.fwtweaeeba );  
        db.documents.save(obj); } );

这个在php中)))

foreach($db->documents->find(array("type" => "chair")) as $document){
    $db->documents->update(
        array('_id' => $document[_id]),
        array(
            '$set' => array(
                'versions.0.content.axdducvoxb' => (float)$document['versions'][0]['content']['axdducvoxb'],
                'versions.1.content.axdducvoxb' => (float)$document['versions'][1]['content']['axdducvoxb'],
                'versions.2.content.axdducvoxb' => (float)$document['versions'][2]['content']['axdducvoxb'],
                'axdducvoxb' => (float)$document['axdducvoxb']
            )
        ),
        array('$multi' => true)
    );


}

答案 12 :(得分:0)

使用mongoose

演示从字符串到mongo objectId的字段更改类型
Code A

Mongo ObjectId只是

等样式的另一个例子

希望答案可以帮助别人的数字,字符串,布尔值。

答案 13 :(得分:0)

在我的情况下,我使用以下

function updateToSting(){
  var collection = "<COLLECTION-NAME>";
  db.collection(collection).find().forEach(function(obj) {
    db.collection(collection).updateOne({YOUR_CONDITIONAL_FIELD:obj.YOUR_CONDITIONAL_FIELD},{$set:{YOUR_FIELD:""+obj.YOUR_FIELD}});
  });
}