前言
在实际开发维护过程中我们可能会遇到需要刷数据的情况,例如修改数据类型,枚举值的变更等。对于数据集较小的操作可以使用循环一个个修改。例如,假定我们之前员工的年龄都录错了,现在每个员工的年龄需要增加1,这个时候可以使用数据集的快照(snapshot)进行逐个更新,就像下面这样:
db.employees.find({age: {$exists: true, $type: 'number'}})
._addSpecial( "$snapshot", true).forEach(function(doc) {
var newAge = doc.age + 1;
db.employees.updateOne({_id: doc._id}, {$set: {age: newAge}});
});
其中下面的代码是告知 MongoDB 使用快照方式一次性读取完整个数据集。
db.employees.find()._addSpecial( "$snapshot", true)
注意的是,在3.x 版本中还有其他两种方式,但是在4.x 版本后已经无法使用。
db.employees.find().snapshot();
db.employees.find({$query: {}, $snapshot: true});
这种方式显然很低效,如果数据集过大没法执行,因此 MongoDB 推出了批量操作 API。
批量操作
批量操作可以支持按批量写入的方式一次同步多条数据到服务端。这使得在 forEach
循环中不需要每次都向服务端写入数据。批量操作的代码如下所示:
var snapshot = db.employees.find({age: {$exists: true, $type: 'number'}})
._addSpecial( "$snapshot", true);
bulkUpadteOps = [];
snapshot.forEach(function(doc) {
var newAge = doc.age + 1;
bulkUpadteOps.push({
'updateOne': {
'filter': {'_id': doc._id},
'update': {$set: {age: newAge}}
}
});
if (bulkUpadteOps.length === 100) {
db.employees.bulkWrite(bulkUpadteOps);
bulkUpadteOps = [];
}
});
if (bulkUpadteOps.length > 0) {
db.employees.bulkWrite(bulkUpadteOps);
}
方式就是将需要进行的操作先存入到一个批量操作的数组中,当积累到一定量时再调用 bulkWrite
批量执行对应的操作。最后,有可能数量不是设定批量操作数量的整数倍,因此若还剩余操作未执行,再执行一次即可完成所有的批量更新操作。
$type指定查询数据类型
在查找快照数据时使用了$type
操作符,用于查找匹配的数据类型,$type
可以使用字符串或数字指定数据类型,这些数据类型都是 MongoDB 内置的数据类型,如下所示。其中 number
代表数值类型的别名,包括了如下类型:
Double 32-bit integer 64-bit integer decimal
| 类型 | 数字 | 别名 | 备注 |
|---|---|---|---|
| Double | 1 | "double" | |
| String | 2 | "string" | |
| Object | 3 | "object" | |
| Array | 4 | "array" | |
| Binary data | 5 | "binData" | |
| Undefined | 6 | "undefined" | 已废弃。 |
| ObjectId | 7 | "objectId" | |
| Boolean | 8 | "bool" | |
| Date | 9 | "date" | |
| Null | 10 | "null" | |
| Regular Expression | 11 | "regex" | |
| DBPointer | 12 | "dbPointer" | 已废弃。 |
| JavaScript | 13 | "javascript" | |
| Symbol | 14 | "symbol" | 已废弃。 |
| JavaScript code with scope | 15 | "javascriptWithScope" | 4.4版本后废弃 |
| 32-bit integer | 16 | "int" | |
| Timestamp | 17 | "timestamp" | |
| 64-bit integer | 18 | "long" | |
| Decimal128 | 19 | "decimal" | 3.4版本以后新增 |
| Min key | -1 | "minKey" | |
| Max key | 127 | "maxKey" |
具体可以参考官网文档:MongoDB $type 操作符
总结
本篇介绍了 MongoDB 提供的批量操作 API,借助批量操作 API 可以在维护数据库时提高效率,例如变更数据类型,批量调整数据值等。
文章转载自岛上码农,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




