我正在尝试从 mongo shell 中更改字段的类型。
我正在做这个...
db.meta.update(
{'fields.properties.default': { $type : 1 }},
{'fields.properties.default': { $type : 2 }}
)
但它不工作!
toString
某些文档的字段,here's the little program I've made/used。
更改数据 $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);
});
将字符串字段转换为整数:
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);
});
NumberLong
:db.db-name.find({field-name : {$exists : true}}).forEach( function(obj) { obj.field-name = new NumberLong(obj.field-name); db.db-name.save(obj); } );
从 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”的值为双精度值时转换为字符串,这匹配“a”类型为 1(双精度)的元素。此表提供了代表不同可能类型的代码。
它过滤要更新的文档。
在这种情况下,由于我们希望将“a”的值为双精度值时转换为字符串,这匹配“a”类型为 1(双精度)的元素。
此表提供了代表不同可能类型的代码。
第二部分 [{ $set: { a: { $toString: "$a" } } }] 是更新聚合管道:注意方括号表示此更新查询使用聚合管道。 $set 是一个新的聚合运算符(Mongo 4.2),在这种情况下会修改一个字段。这可以简单地理解为“$set”将“a”的值转换为“$a”转换为“$toString”。这里真正的新功能是在 Mongo 4.2 中能够在更新文档时引用文档本身:“a”的新值基于“$a”的现有值。另请注意“$toString”,它是 Mongo 4.0 中引入的新聚合运算符。
请注意方括号,表示此更新查询使用聚合管道。
$set 是一个新的聚合运算符(Mongo 4.2),在这种情况下会修改一个字段。
这可以简单地理解为“$set”将“a”的值转换为“$a”转换为“$toString”。
这里真正的新功能是在 Mongo 4.2 中能够在更新文档时引用文档本身:“a”的新值基于“$a”的现有值。
另请注意“$toString”,它是 Mongo 4.0 中引入的新聚合运算符。
不要忘记 { multi: true },否则只会更新第一个匹配的文档。
如果您的转换不是从 double 到 string,您可以选择 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 }
)
db.collection.updateMany( { a : { $type: 1 } }, [{ $set: { a: { $toString: "$a" } } }] )
- 使用 updateMany
可以避免 multi : true
用于字符串到 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);
radix
- developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
new NumberInt()
db.coll.find().forEach(function(data) {
db.coll.update({_id:data._id},{$set:{myfield:parseInt(data.myfield)}});
})
到目前为止,所有答案都使用某些版本的 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',
},
]);
要将字符串类型的字段转换为日期字段,您需要在循环转换中使用 forEach()
方法迭代 find()
方法返回的光标该字段为 Date 对象,然后使用 $set
运算符更新该字段。
利用 Bulk API 进行批量更新,从而提供更好的性能,因为您将以 1000 次为单位向服务器发送操作,这样您就不会发送每个请求,从而获得更好的性能到服务器,每 1000 个请求中只有一次。
下面演示了这种方法,第一个示例使用 MongoDB 版本 >= 2.6 and < 3.2
中提供的 Bulk 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()
提供了一组更新的 api:
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 });
要在 mongo 中将 int32 转换为字符串而不创建数组,只需将“”添加到您的号码:-)
db.foo.find( { 'mynum' : { $type : 16 } } ).forEach( function (x) {
x.mynum = x.mynum + ""; // convert int32 to string
db.foo.save(x);
});
真正帮助我在 MondoDB 中更改对象类型的只是这行简单的代码,可能之前在这里提到过......:
db.Users.find({age: {$exists: true}}).forEach(function(obj) {
obj.age = new NumberInt(obj.age);
db.Users.save(obj);
});
用户是我的集合,年龄是具有字符串而不是整数(int32)的对象。
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);
});
我需要更改集合中多个字段的数据类型,因此我使用以下内容在文档集合中进行了多个数据类型更改。回答一个老问题,但可能对其他人有帮助。
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);
});
演示使用 mongoose 将字段 mid 的类型从字符串更改为 mongo objectId
Post.find({}, {mid: 1,_id:1}).exec(function (err, doc) {
doc.map((item, key) => {
Post.findByIdAndUpdate({_id:item._id},{$set:{mid: mongoose.Types.ObjectId(item.mid)}}).exec((err,res)=>{
if(err) throw err;
reply(res);
});
});
});
Mongo ObjectId 只是此类样式的另一个示例
数字、字符串、布尔值,希望答案对其他人有所帮助。
我在 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)
);
}
new String(x.bad)
创建具有 0-index-itemx.bad
值的字符串集合。由 Simone 描述的变体""+x.bad
按需要工作 - 创建 String 值而不是 Int32db.questions.find({_id:{$type:16}}).forEach( function (x) { db.questions.remove({_id:x._id},true); x._id = ""+x._id; db.questions.save(x); });
.save is not a function
面临此错误