如何将 MongoDB 中的属性从文本类型转换为日期类型?

Posted

技术标签:

【中文标题】如何将 MongoDB 中的属性从文本类型转换为日期类型?【英文标题】:How do I convert a property in MongoDB from text to date type? 【发布时间】:2011-02-23 10:44:05 【问题描述】:

在 MongoDB 中,我有一个文档,其中包含一个名为 "ClockInTime" 的字段,该字段是从 CSV 作为字符串导入的。

将这些基于文本的值转换为日期数据类型的适当db.ClockTime.update() 语句是什么样的?

【问题讨论】:

我想在 Mongo shell 中执行这个语句作为就地更新。 会很高兴看到一些示例数据,即“ClockTime”:“-233744483733” 【参考方案1】:

这段代码应该可以做到:

> var cursor = db.ClockTime.find()
> while (cursor.hasNext()) 
... var doc = cursor.next();
... db.ClockTime.update(_id : doc._id, $set : ClockInTime : new Date(doc.ClockInTime))
... 

【讨论】:

@Kristina - 唷,这节省了我大量的时间,感谢作者提出这样的问题。 只是作为一个旁注(我会被纠正),但如果你从时间戳值转换,字符串将不起作用。它必须是一个长整数。例如,时间戳值 206281199529 在源文件(CSV 或 JSON)中不能是“206281199529”。我不知道为什么不 - 尝试使用 v2.2.2 并且每次将日期设置为纪元。 @Crungmungus 是的,只有日期构造函数采用的形式的日期才会正确转换。有关所有格式,请参阅 developer.mozilla.org/en-US/docs/javascript/Reference/…。 @kristina 我有一个日期,格式为“2003-10-24”。我使用了上面的代码,但所有日期都更改为 1970-01-01.... 我如何使用更新功能? @Shubham 你必须有一个有效的 JavaScript 日期格式,查看developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…。【参考方案2】:

我和 Jeff Fritz 的情况完全一样。

在我的情况下,我通过以下更简单的解决方案取得了成功:

db.ClockTime.find().forEach(function(doc)  
    doc.ClockInTime=new Date(doc.ClockInTime);
    db.ClockTime.save(doc); 
    )

【讨论】:

【参考方案3】:

这是使用 pymongo 在 python 中的通用示例代码

from pymongo import MongoClient
from datetime import datetime

def fixTime(host, port, database, collection, attr, date_format):
    #host is where the mongodb is hosted eg: "localhost"
    #port is the mongodb port eg: 27017
    #database is the name of database eg : "test"
    #collection is the name of collection eg : "test_collection"
    #attr is the column name which needs to be modified
    #date_format is the format of the string eg : "%Y-%m-%d %H:%M:%S.%f"
    #http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior
    client = MongoClient(host, port)
    db = client[database]
    col = db[collection]
    for obj in col.find():
        if obj[attr]:
            if type(obj[attr]) is not datetime:
                time = datetime.strptime(obj[attr],date_format)
                col.update('_id':obj['_id'],'$set':attr : time)

更多信息:http://salilpa.com/home/content/how-convert-property-mongodb-text-date-type-using-pymongo

【讨论】:

【参考方案4】:

开始Mongo 4.x:

db.collection.update() 可以接受聚合管道,最终允许根据字段的当前值 (Mongo 4.2+) 更新字段。 有一个新的 $toDate 聚合运算符 (Mongo 4.0)。

这样:

//  a: "2018-03-03" 
db.collection.update(
  ,
  [ $set:  a:  $toDate: "$a"   ],
   multi: true 
)
//  a: ISODate("2018-03-03T00:00:00Z") 

第一部分 是匹配查询,过滤要更新的文档(在本例中为所有文档)。

第二部分[ $set: a: $toDate: "$a" ] 是更新聚合管道(注意方括号表示使用聚合管道)。 $set 是一个新的聚合运算符,在这种情况下会替换字段的值。被替换的值是字段本身与ISODate 对象一致。注意a是如何直接根据自己的值($a)修改的。

不要忘记 multi: true ,否则只会更新第一个匹配的文档。或者,也可以使用updateMany 而不是updatedb.collection.updateMany(...)

【讨论】:

这是最好的答案(实际上是唯一正确的答案)并且获得了零票:O 你也可以使用updateMany:db.collection.updateMany( , [ $set: a: $toDate: "$a" ] ) 这是一个救命的解决方案......直到我自己尝试过才相信它会起作用。【参考方案5】:

如果你需要检查字段是否已经被转换,你可以使用这个条件:

/usr/bin/mongo mydb --eval 'db.mycollection.find().forEach(function(doc)
    if (doc.date instanceof Date !== true) 
        doc.date = new ISODate(doc.date);
        db.mycollection.save(doc);
    
);'

否则命令行可能会中断。

【讨论】:

以上是关于如何将 MongoDB 中的属性从文本类型转换为日期类型?的主要内容,如果未能解决你的问题,请参考以下文章

从shell中更新/写入到文档的数字,会变为float类型,怎么解决

将 MongoDB 字段从字符串转换为数组中的 ISODate

如何在 MS Access 的追加查询中将数据类型从文本转换为是/否?

如何从输入类型文本中保存字符串列表属性 - App Engine Python

如何将 XML 属性转换为文本节点

MongoDB如何将数组中的字段类型从字符串更改为数组并保持原始值