MongoDB只有时间比较日期

时间:2015-07-07 15:07:37

标签: mongodb

如何仅使用日期查询MongoDB中的日期字段,而不是时间?例如,如果MongoDB将任何时间存储在2015年7月7日,我希望仅将该日与当天的日期相匹配。

在MySQL中,我会SELECT col1, col2 FROM table WHERE DATE(date_field) = DATE(NOW());

注意MySQL如何在匹配期间将 date_field 更改为日期。我可以在匹配过程中使用类似功能在MongoDB中执行此操作吗?像Collection.find({ dateonly(datetimefield): dateonly(new Date() });或类似的东西?

我知道Mongo以GMT格式存储日期/时间,因此我还必须将存储的GMT日期+时间从GMT转换为本地才能匹配日期,但是为了让我开始,想知道我是否可以剥离日期匹配的时间。例如,如果GMT现在是7月8日03:00,但美国东部时间是7月7日23:00,那么我希望在7月7日匹配。

6 个答案:

答案 0 :(得分:5)

我猜你应该在当天的开始和结束之间进行范围查询(如果你今天谈论的话,还是没有结束)。像这样的东西

db.collection.find({
  "date" : {"$gte": new Date("2015-07-07T00:00:00.000Z"),
            "$lt": new Date("2015-07-08T00:00:00.000Z")}
})

答案 1 :(得分:3)

更新2018-06-26修复了使用moment()代替新Date()的代码

所以听起来没有mongodb等同于MySQL DATE函数,就像SELECT col1, col2 FROM table WHERE DATE(date_field) = DATE(NOW())

一样

代替本机解决方案,我通过使用MomentJS时区(http://momentjs.com/timezone/)将日期/时间转换为仅日期数字字段,然后将日期存储为数字来解决此问题。

在我的javascript代码中(在MongoDB之外):

var localDateOnly = function(timezone, d) {
  if (d == undefined) { d = new Date(); } // current date/time
  return Number( moment(d).tz(timezone).format("YYYYMMDD") );
}

然后我在Mongo记录中存储一个仅限日期的字段。

var myDate = localDateOnly("America/New_York");  // today, in YYYYMMDD number
db.birthdays.insert(
  { dateonly: myDate, event: "This day is my birthday!" }
);

然后在我的Javascript代码中,我可以轻松查询今天,明天,特定日期等。

// today
var myDate = localDateOnly("America/New_York");
db.birthdays.find( { dateonly: myDate } );

// tomorrow
var myDate = localDateOnly(
  "America/New_York",
  moment().add( 1, "days" )
);  // tomorrow
db.birthdays.find( { dateonly: myDate } );

// someone wants to know birthdays on the calendar on July 15, 2015
// regardless which time zone they are in
// just find the date in YYYYMMDD format
db.birthdays.find( { dateonly: 20150715 } );

希望这有助于某人。它是为了提高索引的性能而存储数字而不是字符串。我有其他代码强制执行有效的数字,然后在存储到数据库中检查:

moment( 20150715, "YYYYMMDD", true ).isValid()  // returns true & allowed to store in the database
moment( 150715, "YYYYMMDD", true ).isValid()  // returns false, don't insert into db

答案 2 :(得分:2)

这是我提议的解决方案:

db.collection.find({
  $and: [
  {"date": {$gte: new Date("2015-07-07T00:00:00.000Z")}},
  {"date": {$lt: new Date("2015-07-08T00:00:00.000Z")}}
  ]
})

答案 3 :(得分:2)

您可以使用任何给定的格式将日期提取为字符串,然后使用汇总pipiline将其与该格式的日期进行比较

$addFields: { "creationDate":  {$dateToString:{format: "%Y-%m-%d", date: "$createdAt"}}}},
{$match :  { creationDate:  {$eq: req.query.date}}

答案 4 :(得分:1)

可以用 $expr

{ $expr: {$eq: ["2021-03-29", { $dateToString: {date: "$dateField", format: "%Y-%m-%d"}}]}}

答案 5 :(得分:0)

我做了Crash_Override和Maxim_PontyUshenko的答案的组合。使用Moment.js和$ gt,$ lt mongo运算符。

ship_date: {
  $lt: moment().hours(0).minutes(0).seconds(0).milliseconds(0).add(28, "days").toDate(),
  $gte: moment().hours(0).minutes(0).seconds(0).milliseconds(0).toDate()
}