【问题标题】:Mongo consider October 1st and 2nd are different monthsMongo 认为 10 月 1 日和 2 日是不同的月份
【发布时间】:2020-10-01 17:01:47
【问题描述】:

我需要获取一个月的所有记录,例如我创建了以下两条记录:

  • 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

由于存储有小时偏移,我们看到它们属于不同的月份,但是当转换为日期 (JavaScript) 时,我们将得到正确的日期(01/10/2020 和 05/10/2020)。

但是 Mongo 将这两个字段计算在不同的月份,我只得到一个记录。

查询示例:

.aggregate([
                {
                    $addFields: {
                        month: {$month: '$date'},
                    },
                },
                {
                    $match: {
                        month: Number(month),
                    },
                },
            ]);

【问题讨论】:

    标签: javascript database mongodb nosql nestjs


    【解决方案1】:

    当您将日期保存到 Mongo 时,您可能已经注意到它保存为 ISODate 而不是 Date 类型。首先让我们了解什么是ISODate,ISODate() 是一个包装函数,它将所有日期转换为Mongo 易于处理的单个表示。正如他们的docs:

    MongoDB 默认以 UTC 存储时间,并将任何本地时间表示形式转换为这种形式。

    现在你不在UTC时区,我怎么知道?因为您的“正确”时间不是UTC 表示的时间。

    那么,为什么当您在 javascript 中转换它时,您会得到“正确”的时间呢?好吧,根据时区,有很多方法和不同的方法可以将 Date 对象转换为字符串。但是 javascript 使用您的机器时间(我猜这与您的时区同步)进行转换。

    那你能做什么?您需要为您的时区差距调整聚合,假设所有记录都来自同一个时区,您可以这样做:

    • (在这种情况下,假设您比 UTC 提前 5 小时,因此我们希望将 1000 * 60 * 60 * 5 = 18000000 毫秒添加到 Mongo 日期)
    db.collection.aggregate([
        {
            "$addFields": {
                month: {
                    $month: {
                        $add: [
                            "$date",
                            18000000 // 5 hours in milliseconds
                        ]
                    },
                }
            }
        },
        {
            $match: {
                month: Number(month)
            }
        }
    ]);
    

    如果您正在收集来自不同时区的文档,那么您需要保存一个 offset 字段作为您将时间保存到数据库中以帮助计算。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-03
      • 2021-04-06
      • 1970-01-01
      • 2011-06-20
      • 1970-01-01
      相关资源
      最近更新 更多