Mongodb 如何使用mongo聚合将字符串转换为日期?
在集合中,我存储这种文档Mongodb 如何使用mongo聚合将字符串转换为日期?,mongodb,date,mongoose,aggregation-framework,Mongodb,Date,Mongoose,Aggregation Framework,在集合中,我存储这种文档 { "_id" : 1, "created_at" : "2016/01/01 12:10:10", ... }. { "_id" : 2, "created_at" : "2016/01/04 12:10:10", ... } 我希望通过使用聚合管道发现文件已“在”>2016/01/01提交” 任何人都有将“created_at”转换为date的解决方案,以便可以在聚合中进行比较?如您所述,您需要首先更改模式,以便在c
{
"_id" : 1,
"created_at" : "2016/01/01 12:10:10",
...
}.
{
"_id" : 2,
"created_at" : "2016/01/04 12:10:10",
...
}
我希望通过使用聚合管道发现文件已“在”>2016/01/01提交”
任何人都有将“created_at”转换为date的解决方案,以便可以在聚合中进行比较?如您所述,您需要首先更改模式,以便在
created_at
字段中保存日期对象,而不是当前情况下的字符串,然后,您可以使用方法或聚合框架查询集合。前者将是最简单的方法
要将在处创建的转换为日期字段,您需要使用方法迭代方法返回的光标,在循环内将在
处创建的字段转换为日期对象,然后使用操作符更新字段
利用进行批量更新,这样可以提供更好的性能,因为您将以成批的方式(例如1000次)向服务器发送操作,这样可以提供更好的性能,因为您不是每1000次请求中就向服务器发送一次请求
下面演示了这种方法,第一个示例使用MongoDB版本=2.6和<3.2
中提供的批量API。它更新了所有内容
通过将
处创建的字段更改为日期字段,可以删除集合中的文档:
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(); }
下一个示例适用于新的MongoDB版本3.2
,该版本自发布以来一直,并使用提供了一组更新的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 } });
如果希望使用聚合框架进行查询,请运行以下管道以获得所需的结果。它使用运算符,与方法类似:
var dt = new Date("2016/01/01");
db.collection.aggregate([
{
"$match": { "created_at": { "$gt": dt } }
}
])
如果我们有文件:
db.doc.save({ "_id" : 1, "created_at" : "2016/01/01 12:10:10" })
db.doc.save({ "_id" : 2, "created_at" : "2016/01/04 12:10:10" })
简单查询:
db.doc.find({ "created_at" : {"$lte": Date()} })
聚合查询:
db.doc.aggregate([{
"$match": { "created_at": { "$lte": Date() } }
}])
- 方法,该方法以字符串形式返回当前日期李>
- 新的Date()构造函数,它使用ISODate()包装返回日期对象
- ISODate()构造函数,使用ISODate()返回日期对象 包装纸
有关日期类型和的更多信息上述所有答案都使用
游标
,但是,mongodb始终建议使用聚合
管道。使用mongodb 3.6
中的新$dateFromString
,它非常简单。
在聚合管道中无法将字符串转换为日期,而可以将日期转换为字符串。你可能会耍花招:创建你的收藏的副本,并将
created_储存在
作为ISODate,然后比较日期……你实际上不需要为你的查询转换任何东西{created_at:{$gt:'2016/01/01'}}
在这里可以正常工作,因为您的字符串格式支持有意义的比较。@JohnnyHK:它工作得很好,我不认识它。非常感谢,我有没有办法不用转换就将日期作为字符串列搜索为实际日期列?有没有人能帮上忙?我知道这是一个老版本,但是db.collection.bulkWrite(bulkUpdateOps)代码>应该是db.collection.bulkWrite(bulkOps)代码>在你的Monbodb>v3.2答案中。@PhilippeHaussmann Good spot;)我已经纠正了打字错误,谢谢你,没问题!代码片段对我现在正在做的事情非常有帮助。谢谢你把它放在一起!:D你能帮个忙吗?
db.collection.aggregate([
{$project:{ created_at:{$dateFromString:{dateString:'$created_at'}}}}
])