如果您保存在数据库中的日期没有时间(只是年、月、日),那应该可以工作。
您保存的日期可能是 new Date()
,其中包括时间组件。要查询这些时间,您需要创建一个包含一天中所有时刻的日期范围。
db.posts.find({ //query today up to tonight
created_on: {
$gte: new Date(2012, 7, 14),
$lt: new Date(2012, 7, 15)
}
})
...5 年后,我强烈建议改用 date-fns
import endOfDayfrom 'date-fns/endOfDay'
import startOfDay from 'date-fns/startOfDay'
MyModel.find({
createdAt: {
$gte: startOfDay(new Date()),
$lte: endOfDay(new Date())
}
})
对于我们这些使用 Moment.js 的人
const moment = require('moment')
const today = moment().startOf('day')
MyModel.find({
createdAt: {
$gte: today.toDate(),
$lte: moment(today).endOf('day').toDate()
}
})
重要提示:all moments are mutable!
tomorrow = today.add(1, 'days')
不起作用,因为它也会改变 today
。调用 moment(today)
通过隐式克隆 today
解决了这个问题。
.startOf('day')
而不是 .hours(0).minutes(0).seconds(0)。所以第一行是:var today = moment().startOf('day')
moment(today)
克隆对象,另一种解决方案是:var tomorrow = today.clone().add(1, 'days')
$lt
建议以下内容:moment(today).endOf('day')
。防止第二天的实际结果被包括在内。
moment(today).endOf('day')
给出了同一天的时间:23:59:59.999
。所以实际上使用 $lte
看起来更正确,否则该特定时间的对象将被忽略。
是的,Date 对象会完成日期和时间,因此仅将其与日期值进行比较是行不通的。
您可以简单地使用 $where 运算符来使用 Javascript 布尔表达式表达更复杂的条件 :)
db.posts.find({ '$where': 'this.created_on.toJSON().slice(0, 10) == "2012-07-14"' })
created_on
是日期时间字段,2012-07-14
是指定日期。
日期应完全采用 YYYY-MM-DD 格式。
注意:请谨慎使用 $where
,它会影响性能。
db.posts.find({ $expr: { $function: { body: function(created_on) { return created_on.toJSON().slice(0, 10) == "2012-07-14"' }, args: ["$created_on"], lang: "js" } } } )
你有没有尝试过:
db.posts.find({"created_on": {"$gte": new Date(2012, 7, 14), "$lt": new Date(2012, 7, 15)}})
您将遇到的问题是日期在 Mongo 中存储为时间戳。因此,要匹配日期,您要求它匹配时间戳。在您的情况下,我认为您正在尝试匹配一天(即从特定日期的 00:00 到 23:59)。如果您的日期没有时间存储,那么您应该没问题。否则,如果 gte 不起作用,请尝试将您的日期指定为同一天的时间范围(即 start=00:00,end=23:59)。
$gte
而不是 gte
会更好。
您可以对 API 方法使用以下方法来获取特定日期的结果:
# [HTTP GET]
getMeals: (req, res) ->
options = {}
# eg. api/v1/meals?date=Tue+Jan+13+2015+00%3A00%3A00+GMT%2B0100+(CET)
if req.query.date?
date = new Date req.query.date
date.setHours 0, 0, 0, 0
endDate = new Date date
endDate.setHours 23, 59, 59, 59
options.date =
$lt: endDate
$gte: date
Meal.find options, (err, meals) ->
if err or not meals
handleError err, meals, res
else
res.json createJSON meals, null, 'meals'
我用这种方法做的,效果很好
public async getDatabaseorderbyDate(req: Request, res: Response) {
const { dateQuery }: any = req.query
const date = new Date(dateQuery)
console.log(date)
const today = date.toLocaleDateString(`fr-CA`).split('/').join('-')
console.log(today)
const creationDate = {
"creationDate": {
'$gte': `${today}T00:00:00.000Z`,
'$lt': `${today}T23:59:59.999Z`
}
};
`
``
我遇到的问题是在后端过滤日期,当在节点服务器中将日期设置为 0 小时、0 分钟、0 秒、0 毫秒时,它在 ISO 时间中执行,因此客户端的当前日期可能为 0 小时、0 分钟、0 秒、0 毫秒由于 ISO 时间到本地时区的转换,结果可能会在之后或之前给出一天
我通过将本地时间从客户端发送到服务器来解决这些问题
// If client is from Asia/Kathmandu timezone it will zero time in that zone.
// Note ISODate time with zero time is not equal to above mention
const timeFromClient = new Date(new Date().setHours(0,0,0,0)).getTime()
并利用这段时间使用此查询过滤文档
const getDateQuery = (filterBy, time) => {
const today = new Date(time);
const tomorrow = new Date(today.getDate() + 1);
switch(filterBy) {
case 'past':
return {
$exists: true,
$lt: today,
};
case 'present':
return {
$exists: true,
$gte: today,
$lt: tomorrow
};
case 'future':
return {
$exists: true,
$gte: tomorrow
};
default:
return {
$exists: true
};
};
};
const users = await UserModel.find({
expiryDate: getDateQuery('past', timeFromClient)
})
我们在数据库中遇到了与重复数据有关的问题,日期字段有多个值,而我们本来应该有 1 个值。我想我会添加解决问题的方式以供参考。
我们有一个名为“数据”的集合,其中包含一个数字“值”字段和一个日期“日期”字段。我们有一个我们认为是幂等的过程,但最终在第二次运行时每天添加 2 x 值:
{ "_id" : "1", "type":"x", "value":1.23, date : ISODate("2013-05-21T08:00:00Z")}
{ "_id" : "2", "type":"x", "value":1.23, date : ISODate("2013-05-21T17:00:00Z")}
我们只需要 2 条记录中的 1 条,因此不得不使用 javascript 来清理数据库。我们最初的方法是遍历结果并删除时间在早上 6 点到 11 点之间的任何字段(所有重复项都在早上),但在实施过程中进行了更改。这是用于修复它的脚本:
var data = db.data.find({"type" : "x"})
var found = [];
while (data.hasNext()){
var datum = data.next();
var rdate = datum.date;
// instead of the next set of conditions, we could have just used rdate.getHour() and checked if it was in the morning, but this approach was slightly better...
if (typeof found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()] !== "undefined") {
if (datum.value != found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()]) {
print("DISCREPENCY!!!: " + datum._id + " for date " + datum.date);
}
else {
print("Removing " + datum._id);
db.data.remove({ "_id": datum._id});
}
}
else {
found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()] = datum.value;
}
}
然后用 mongo thedatabase fixer_script.js
运行它
似乎没有一个答案对我有用。尽管有人提到了一点提示,但我设法使它与下面的代码一起工作。
let endDate = startingDate
endDate = endDate + 'T23:59:59';
Model.find({dateCreated: {$gte: startingDate, $lte: endDate}})
startingDate
将是您要查询的具体日期。
我更喜欢这个解决方案,以避免安装 moment
,而只是在邮递员中传递 startingDate
,如 "2021-04-01"
。
下面给出了一个非常简单的解决方案
const start = new Date(2020-04-01);
start.setHours(0, 0, 0, 0);
const end = new Date(2021-04-01);
end.setHours(23, 59, 59, 999);
queryFilter.created_at={
$gte:start,
$lte:end
}
YourModel.find(queryFilter)
因此,上面的代码只是查找从给定开始日期到给定结束日期的记录。