正如您所提到的,您需要首先更改您的架构,以便 created_at 字段包含日期对象而不是当前情况下的字符串,然后您可以使用 find() 查询您的集合 方法或聚合框架。前者将是最简单的方法。
要将created_at 转换为日期字段,您需要在循环中使用forEach() 方法迭代find() 方法返回的光标将 created_at 字段转换为 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 cursor = db.collection.find({"created_at": {"$exists": true, "$type": 2 }}),
bulkOps = [];
cursor.forEach(function (doc) {
var newDate = new Date(doc.created_at);
bulkOps.push(
{
"updateOne": {
"filter": { "_id": doc._id } ,
"update": { "$set": { "created_at": newDate } }
}
}
);
if (bulkOps.length === 1000) {
db.collection.bulkWrite(bulkOps);
bulkOps = [];
}
});
if (bulkOps.length > 0) { db.collection.bulkWrite(bulkOps); }
架构修改完成后,您可以查询您的集合的日期:
var dt = new Date("2016/01/01");
db.collection.find({ "created_at": { "$gt": dt } });
如果您希望使用聚合框架进行查询,请运行以下管道以获得所需的结果。它使用 $match 运算符,类似于 find() 方法:
var dt = new Date("2016/01/01");
db.collection.aggregate([
{
"$match": { "created_at": { "$gt": dt } }
}
])