我正在尝试查询Atlas(免费层(上托管的MongoDB。我正在使用nextjs来构建api。我试图用vercel(以前称为zeit(托管它。代码在本地工作正常。在部署到云(vercel(时,它不起作用。
var MongoClient = require('mongodb').MongoClient;
// serverless function for proverbs of the day
export default async (req, res) => {
return new Promise((resolve) => {
let databaseString = process.env.DATABASE_URL;
MongoClient.connect(
databaseString,
{ useUnifiedTopology: true },
async function (err, client) {
if (err) {
console.error(err);
throw err;
}
var db = client.db('database_name');
var start = new Date();
start.setHours(0, 0, 0, 0);
var end = new Date();
end.setHours(23, 59, 59, 999);
let result;
try {
// query 1 : doesn't works
result = await db
.collection('proverbs')
.findOne({ createdAt: { $gt: start, $lt: end } });
// query 2 : works
// result = await db.collection('proverbs').findOne({'id': 11 })
} catch (err) {
console.error(err);
} finally {
client.close();
}
res.send(result);
return resolve();
},
);
});
};
我尝试了两个查询:查询 1 和查询 2
在本地查询1 和 2 中都有效
在Vercel云服务器查询1不起作用 查询 2 作品
我想让查询 1 工作。我哪里出错了?
问题可能来自您的计算机和 Vercel 服务器之间的时区差异。建议尽可能多地使用 UTC 时间以避免此类问题。
在您的情况下,简单地使用setUTCHours
而不是setHours
应该会在生产中为您提供与 localhost 相同的结果。
问题可能来自您的机器和 Vercel 服务器之间的时区差异,正如 @Maxim Orlov 所回答的那样。但我不能对他的回答投赞成票,因为将设置小时设置为设置UTCHours并不能解决问题。以下是我发现的:
解决方案
旧:这不起作用
result = await db
.collection('proverbs')
.findOne({ createdAt: { $gt: start, $lt: end } });
新:此作品
result = await db
.collection('proverbs')
.findOne({ createdAt: { $gte: start, $lt: end } });
// also using setUTCHours instead of setHour is recommended, since UTC time is used.
解释
我有很多文档的时间戳为以下格式 - 2020-06-01 00:00:00.000 - 2020-06-02 00:00:00.000 - 等等。
案例 1:为什么代码在本地给出结果?
- 本地计算机时区设置为 +05:30
- 数据使用 UTC 时间存储在 Mongodb(阿特拉斯(中,例如 UTC 中的 2020-06-03 00.00.00 。
- 在本地机器中,时间为 2020-06-03 11:00:00(即 +05:30(
- let start = new Date.setHours(0,0,0,0( 即 2020-06-02 18:30:00.000
- let end = new Date.setHours(23, 59, 59, 999( 即 2020-06-03 18:29:59.999
- 结果 = 等待数据库 .collection("箴言"( .findOne({ createdAt: { $gt: start, $lt: end } }(; 创建于 (2020-06-03 00:00:00.000(>开始 (2020-06-02 18:30:00.000( 并创建于 (2020-06-03 00:00:
- 00.000(<结束>结束>
案例 2:为什么代码在生产(vercel 服务器(中没有给出结果?
- Vercel 机器时区设置为 +00:00
- 数据使用 UTC 时间存储在 Mongodb(阿特拉斯(中,例如 UTC 中的 2020-06-03 00.00.00 。
- 在Vercel机器中,时间为2020-06-03 05:30:00(即+00:00,即UTC(
- let start = new Date.setHours(0,0,0,0( 即 2020-06-03 00:00:00.000
- let end = new Date.setHours(23, 59, 59, 999( 即 2020-06-03 23:59:59.999
- 结果 = 等待数据库 .collection("箴言"( .findOne({ createdAt: { $gt: start, $lt: end } }(; 创建于 (2020-06-03 00:00:00.000(>开始 (2020-06-03 00:00:00.000( 并在<结束>( 创建于 (2020-06-03 23:59:59.000(。 这是(假和真(,因此是假的,没有返回结果。 结束>
注意:
- 服务器时间设置为 UTC
- 因此 setHour 和 setUTCHour 将给出相同的时间
- 为避免机器与Vercel服务器之间的时区差异问题,请始终使用UTC