我需要将字段类型从int32更改为string。此更改适用于服务器中的数据和大量文档。
通过类似以下的简单更新,由于时间问题,只有一小部分文档得到更新:
APP_URL
所以我决定进行批量更改:
db.collection.find({"identifier": {$exists:true}})
.forEach( function(x) {
db.collection.update({_id: x._id}, {$set: {"identifier":
x.identifier.toString()}});
}
);
但是它给出了一个错误并且没有被执行。
如何使更新生效?
答案 0 :(得分:1)
没有批量更新,您无法在官方docs中定义函数。 您可以做的是使用skip和limit重新创建批量操作。
为此,您必须定义要使用的跳过和限制值。如果要使用100的批处理量进行更新,则限制始终为100,但是每次运行查询时,跳过次数都会增加100。
例如,第一次运行。
db.collection.find({"identifier": {$exists:true}}).sort({_id:1}).skip(0).limit(100)
.forEach( function(x) {
db.collection.update({_id: x._id}, {$set: {"identifier":
x.identifier.toString()}});
}
);
例如第二次。
db.collection.find({"identifier": {$exists:true}}).sort({_id:1}).skip(100).limit(100)
.forEach( function(x) {
db.collection.update({_id: x._id}, {$set: {"identifier":
x.identifier.toString()}});
}
);
例如,第三轮。
db.collection.find({"identifier": {$exists:true}}).sort({_id:1}).skip(200).limit(100)
.forEach( function(x) {
db.collection.update({_id: x._id}, {$set: {"identifier":
x.identifier.toString()}});
}
);
通过这种方式,您可以控制每100个大小为100的批处理。
请记住在跳过和限制之前始终进行排序,否则跳过操作会产生随机结果。您可以根据需要的条件进行排序。
如果find操作过滤了需要转换的结果,您还可以帮助该过程:
db.collection.find({"identifier": {$exists:true, $not {$type: "string"} }})
.forEach( function(x) {
db.collection.update({_id: x._id}, {$set: {"identifier":
x.identifier.toString()}});
}
);
但是不要同时使用这两种方法,而要选择一种或另一种方法(因为find操作的结果)。
希望这会有所帮助。