Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 如何使用mongo聚合将字符串转换为日期?_Mongodb_Date_Mongoose_Aggregation Framework - Fatal编程技术网

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'}}}}
])