将字段转换为正确日期对象的一种方法是在给定的分隔符"-" 上拆分字符串。使用 parseInt() 将分隔的字符串转换为数字,new Date() 构造函数从这些部分构建 Date:第一个一部分是年份,第二部分是月份,最后一部分是日期。由于 Date 使用从零开始的月份编号,因此您必须从月份编号中减去 1。
以下演示了这种方法:
var cursor = db.patient.find({"birthDate": {"$exists": true, "$type": 2 }});
while (cursor.hasNext()) {
var doc = cursor.next();
var parts = doc.birthDate.split("-");
var dt = new Date(
parseInt(parts[0], 10), // year
parseInt(parts[1], 10) - 1, // month
parseInt(parts[2], 10) // day
);
db.patient.update(
{"_id": doc._id},
{"$set": {"birthDate": dt}}
)
};
为了提高性能,尤其是在处理大型集合时,请利用 Bulk API 进行批量更新,因为您将以 500 个批量将操作发送到服务器,从而为您提供更好的性能,因为您不会将每个请求都发送到服务器,每 500 个请求只发送一次。
下面演示了这种方法,第一个示例使用了 MongoDB 版本>= 2.6 and < 3.2 中可用的 Bulk API。它更新所有
通过将 OrderDate 字段更改为日期字段来获取集合中的文档:
var bulk = db.patient.initializeUnorderedBulkOp(),
counter = 0;
db.patient.find({"birthDate": {"$exists": true, "$type": 2 }}).forEach(function (doc) {
var parts = doc.birthDate.split("-");
var dt = new Date(
parseInt(parts[0], 10), // year
parseInt(parts[1], 10) - 1, // month
parseInt(parts[2], 10) // day
);
bulk.find({ "_id": doc._id }).updateOne({
"$set": { "birthDate": dt}
});
counter++;
if (counter % 500 == 0) {
bulk.execute(); // Execute per 500 operations and re-initialize every 500 update statements
bulk = db.patient.initializeUnorderedBulkOp();
}
})
// Clean up remaining operations in queue
if (counter % 500 != 0) { bulk.execute(); }
下一个示例适用于自 deprecated the Bulk API 以来的新 MongoDB 版本 3.2,并使用 bulkWrite() 提供了一组更新的 api:
var bulkOps = db.patient.find({"birthDate": {"$exists": true, "$type": 2 }}).map(function (doc) {
var parts = doc.birthDate.split("-");
var dt = new Date(
parseInt(parts[0], 10), // year
parseInt(parts[1], 10) - 1, // month
parseInt(parts[2], 10) // day
);
return {
"updateOne": {
"filter": { "_id": doc._id } ,
"update": { "$set": { "birthDate": dt } }
}
};
})
db.patient.bulkWrite(bulkOps);