MongoDB 日期查询

问题描述 投票:0回答:1

我有一个名为

practices
的集合,用于存储用户所做的实践文档。我每个文档中有 4 个密钥。

  • 开始时间(日期时间戳)
  • 结束时间(日期时间戳)
  • 用户(用户的objectID)
  • 持续时间(练习时长,以秒为单位)

现在混乱了。由于我的时区是 (距 UTC +5:00),假设我提交了一个带有

startTime=2024-10-10T01:00:00+05:00
的实践,该实践将作为
startTime=2024-10-09T20:00:00Z
存储在 MongoDB 中,因为 MongoDB 以 UTC 存储日期时间,这会将提交的时间戳移回到 -5 小时,最终移至之前的日期,从 10 到 09。不同的用户会有不同的时区。

现在,我想查询一个用户当天的全部行为。我使用 dayjs 进行日期操作。

我生成这样的查询:

const queryDay = '2024-10-10'

query = {
  startTime: {
  $gte: dayjs.utc(queryDay).startOf('day).toDate()
 },
  endTime: {
  $lte: dayjs.utc(queryDay).endOf('day).toDate()
 }
}

结果 startTime=2024-10-10T00:00:00ZendTime=2024-10-10T23:59:59Z

现在,当查询运行时,它将错过上面提交的实践,因为它是用不属于查询的日期时间保存的,但从技术上讲,它应该包含在内,因为它发生在10,但根据(+5: 00).

根据我的想法,开始日和结束日会根据时区而有所不同。当我的一天开始于2024-10-10T00:00:00+05:00时,这次转换为UTC等于2024-10-09T19:00:00Z,一天结束时也是如此,一天结束于 2024-10-10T23:59:59+05:00,UTC 等于 2024-10-10T18:59:59Z。如果我们使用这些 startTime 和 endTime 那么它将准确地获取当天的所有练习。

这些是我的主要问题:

  1. 那么我该怎么做呢?意味着我如何构建尊重用户的查询 谁正在获取它的时区。
  2. 我对dayjs的toDate()方法有疑问。它在节点和浏览器环境中的行为有所不同。在浏览器中,它给了我一个在本地时区解析的日期对象。就我而言(+5:00),当在节点中时,它只是首先将日期转换为 UTC,然后转换为日期对象(不会在服务器时区或任何时区中进行解析)。如果在节点中它将日期对象转换为服务器运行的本地时区,会发生什么,因为这会搞乱查询?
  3. 有没有一种方法可以让我们使用 ISO 字符串来在查询中使用它。我听说它只使用日期对象来查询日期字段,不接受字符串(ISO日期字符串)?我不想使用 toDate() 因为它的行为不一致。
javascript node.js mongodb date dayjs
1个回答
0
投票

您可以将输入输入到

$dateFromParts
中,让 Mongo 为您生成具有正确时区的日期输入。我个人建议将
$let
链接起来以使其参数化。

db.collection.find({
  "$expr": {
    "$let": {
      "vars": {
        "inputDate": {
          "$dateFromParts": {
            // your input here
            "year": 2024,
            "month": 10,
            "day": 10,
            "timezone": "+05:00"
          }
        }
      },
      "in": {
        "$let": {
          "vars": {
            "inputDateStart": "$$inputDate",
            "inputDateEnd": {
              "$dateAdd": {
                "startDate": "$$inputDate",
                "unit": "day",
                "amount": 1
              }
            }
          },
          in: {
            "$and": [
              {
                "$gte": [
                  "$startTime",
                  "$$inputDate"
                ]
              },
              {
                $lt: [
                  "$endTime",
                  "$$inputDateEnd"
                ]
              }
            ]
          }
        }
      }
    }
  }
})

蒙戈游乐场

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.