问题描述
- 2020年10月1日(2020- 09 -30T21:00:00.000 + 00:00)
- 2020年10月5日(2020- 10 -04T21:00:00.000 + 00:00)
Example entries in the database
由于存储时间偏移了一个小时,我们看到它们属于不同的月份,但是当转换为Date(JavaScript)时,我们将获得正确的日期(01/10/2020和05/10/2020)。 / p>
但是Mongo 计算了不同月份的这两个字段,而我只得到一条记录。
查询示例:
.aggregate([
{
$addFields: {
month: {$month: '$date'},},{
$match: {
month: Number(month),]);
解决方法
当您将日期保存到Mongo时,您可能已经注意到它被保存为ISODate
而不是Date
类型。首先让我们了解什么是ISODate
,ISODate()
是一个包装函数,它将所有日期转换为Mongo易于处理的单个表示形式。根据他们的docs中的规定:
默认情况下,MongoDB将时间存储在UTC中,并将所有本地时间表示形式转换为这种形式。
现在您不在UTC
时区,我怎么知道?因为您的“正确”时间不是UTC
表示的时间。
那么,为什么在javascript中进行转换时却获得了“正确的”时间?同样,根据时区,有很多方法和不同方法可以将Date
对象转换为字符串。但是javascript使用您的机器时间(我想它会同步到您的时区)进行转换。
那你该怎么办?您需要调整时区间隔的汇总,假设所有记录都来自同一时区,您可以执行以下操作:
- (在这种情况下,假设您比
UTC
早5个小时,因此我们想在Mongo日期前加上1000 * 60 * 60 * 5 = 18000000毫秒)
db.collection.aggregate([
{
"$addFields": {
month: {
$month: {
$add: [
"$date",18000000 // 5 hours in milliseconds
]
},}
}
},{
$match: {
month: Number(month)
}
}
]);
如果要从不同时区收集文档,则需要保存一个offset
字段,以便将时间保存到数据库中以帮助进行计算。