在MongoDB中存储日期的最佳方式是什么?

在MongoDB中存储日期的最佳方式是什么?,mongodb,Mongodb,我刚刚开始学习MongoDB,希望能慢慢地从MySQL迁移 在MySQL中,有两种不同的数据类型-DATE('0000-00-00')和DATETIME('0000-00-00 00:00:00')。在我的MySQL中,我使用DATE类型,但我不知道如何将它们传输到MongoDB中。在MongoDB中,有一个Date对象,它与DATETIME相当。似乎最适合使用Date对象,但这会浪费空间,因为没有使用小时、分钟、秒。另一方面,将日期存储为字符串似乎是错误的 MongoDB中是否有存储日期的黄金

我刚刚开始学习MongoDB,希望能慢慢地从MySQL迁移

在MySQL中,有两种不同的数据类型-
DATE('0000-00-00')
DATETIME('0000-00-00 00:00:00')
。在我的MySQL中,我使用
DATE
类型,但我不知道如何将它们传输到MongoDB中。在MongoDB中,有一个
Date
对象,它与
DATETIME
相当。似乎最适合使用
Date
对象,但这会浪费空间,因为没有使用小时、分钟、秒。另一方面,将日期存储为字符串似乎是错误的


MongoDB中是否有存储日期的黄金标准('0000-00-00')?

如果您真的关心每个字段节省4字节(如果每个文档中有许多
日期
字段),您可以将日期存储为
int32
字段,格式为
20110720
(注意MySQL
DATE
占用3个字节,因此在任何情况下存储空间都会更大)。否则,我最好坚持使用标准的datetime类型。

BSON(mongo本机使用的存储数据格式)有一个64位(8字节)的有符号整数,表示从Unix时间纪元开始的毫秒数。很少有正当理由说明为什么要使用任何其他类型来存储日期和时间戳

如果您非常想在每个日期保存几个字节(同样,使用mongo的填充和最小块大小以及所有只有在极少数情况下才值得费事的东西),您可以将日期存储为3字节二进制blob,方法是将其存储为YYYYMMDD格式的无符号整数,或2字节二进制blob,表示“从X年1月1日起的天数”其中X必须正确选择,因为它只支持跨越179年的日期范围


编辑:正如下面的讨论所表明的,这只是在非常罕见的情况下可行的方法。基本上;使用mongo的原生日期类型;)

我实际上正在转换MongoDB数据库,其中日期存储为适当的日期()类型,而不是以
yyyy-mm-dd
的形式存储为字符串。为什么,考虑到其他回答者都说这是个可怕的想法?简单地说,因为我一直在努力用JavaScript处理日期,而JavaScript没有(真正的)时区概念,所以我一直在忍受着无尽的痛苦。我一直在MongoDB中存储UTC日期,即一个日期()对象,其中包含我想要的日期和设置为午夜UTC的时间,但要将用户提交的日期正确地转换为他们所处的任何时区的日期,这出乎意料地复杂且容易出错。我一直在努力让我的JavaScript“从本地时区到UTC”代码正常工作(是的,我知道Sugar.js和Moment.js),我决定使用简单的字符串,比如旧的MySQL标准
yyyy-mm-dd
,我将在客户端运行时根据需要解析为Date()对象


顺便说一句,我还尝试将这个MongoDB数据库与FileMaker数据库同步,FileMaker数据库也没有时区的概念。对我来说,简单地不存储时间数据,特别是像UTC midnight这样毫无意义的时间数据,有助于确保更少的错误代码,即使我必须时不时地解析字符串日期。

二进制字段包括4字节长度和1字节子类型,因此空二进制字段占用5字节。我知道。澄清一下,这将是在一个blob中存储多个日期。要花费大量精力删除几个字节,唯一有效的理由是当您有很多日期要存储时。我认为这是在OP中暗示的。这种存储方式也会使日期不可索引,更新起来也很繁琐。开发打包的想法可以使用一些快速压缩库(比如GoogleSnappy)。有效的用例是避免在JavaScript中处理时区的困难。见下面我的答案。我发现解析/格式化字符串(如
yyyy-mm-dd
)比尝试协调客户端和服务器时区并在适当的日期创建
Date()
对象更容易。记住我们在这里只保存日期,而不是日期时间。@Geoffrey我指的是使用二进制数据存储日期。将它们存储为字符串是完全有效的。也就是说,我强烈建议不要在服务器端处理时区,并将所有内容存储为UTC。之后,您可以在客户端上进行时区转换。要干净得多。投票。根据UTC日期/时间将日期存储为BSON的最大缺点是没有存储。它使您能够处理它们根本不适用的时区,这比解析简单的日期字符串要困难得多。我还建议在MongoDB中将日期表示为字符串。我还惊喜地发现,
$gt
$lt
可以根据需要使用存储为字符串的日期:
.find({created:{$gt:'2012-01-01'}})
实际上会返回自2012年1月1日以来创建的所有文档。我很高兴我没有使用
yyyy-mm-dd
在MongoDB中存储日期。这样,您就失去了所有的日期聚合选项。@ukaszFrankowski,从3.6版开始,您可以使用$dateFromString。@DanDascalescu:这不是重复的。您提到的讨论是关于日期/时间,而这里是关于如何存储没有时间的日期。