我有一个名为
practices
的集合,用于存储用户所做的实践文档。我每个文档中有 4 个密钥。
现在混乱了。由于我的时区是 (距 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:00Z 和 endTime=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 那么它将准确地获取当天的所有练习。
这些是我的主要问题:
您可以将输入输入到
$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"
]
}
]
}
}
}
}
}
})