2016-02-29 92 views
2

我有我的birthDate字符串格式是这样的“2010-03-22”。我想在MongoDB中的Date类型中进行转换。转换日期从字符串格式到日期格式在mongodb

应该写什么db.patient.update()函数? 我想计算每个人的年龄。

我使用了How do I convert a property in MongoDB from text to date type?上的解决方案,但所有日期都转换为“1970-01-01T00:00:00.000Z”。

+0

你会使用什么客户端? C#,Java的JavaScript? - >可以指向需要的端口代码 – profesor79

回答

1

一种方法是通过在分隔符"-"给定分裂的字符串。使用parseInt()到分隔字符串转换为数字,而new Date()构造函数建立从这些零件一个Date:第一部分将是今年,第二部分的一个月,一天的最后一部分。由于Date使用从零开始的月份数字,您必须从月份数字中减去一个。

下面演示了这种方法:

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(); } 

下一个例子适用于新的MongoDB版本3.2这已经deprecated the Bulk API,并提供了新的一套使用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); 
+1

非常感谢它的工作...... :) – RAFA

2
db.collection.find().forEach(function(e){ 
e.fieldname = new Date(e.fieldname) 
db.collection.save(e) 
}); 

如果您正在使用robomonogo使用新ISODate而不是新的日期,你可以采取在现场转换为正确的日期对象