MongoDB /猫鼬在特定日期查询?


141

是否可以查询特定日期?

我在mongo Cookbook中发现我们可以针对某个范围进行查询 ,例如:

db.posts.find({"created_on": {"$gte": start, "$lt": end}})

但是可能有特定的日期吗?这不起作用:

db.posts.find({"created_on": new Date(2012, 7, 14) })

Answers:


210

如果您保存在数据库中的日期没有时间(恰好是年,月,日),那应该可以。

您保存的日期可能是new Date(),其中包括时间成分。要查询这些时间,您需要创建一个包含一天中所有时刻的日期范围。

db.posts.find( //query today up to tonight
  {"created_on": {"$gte": new Date(2012, 7, 14), "$lt": new Date(2012, 7, 15)}})

28
请记住,在date()函数,当月参数从0开始计数,而不是1。另一方面,在天1点...开始计数的细节
马克Stosberg

难道不是要用_天来获得下一个日期而不是对两个人都进行硬编码?
raju 2015年

2
如果这样存储日期,此方法是否可以正常工作:>>“日期”:ISODate(“ 2016-01-04T14:07:17.496Z”)
santhosh 2016年

您没有月份和日期切换功能。日期格式应为:yyyy,dd,MM
thethakuri

123

... 5年以上后,我强烈建议使用日期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()
  }
})

重要提示:所有时刻都是可变的

tomorrow = today.add(1, 'days')不起作用,因为它也会突变today。调用moment(today)通过隐式克隆解决了该问题 today


13
我建议使用.startOf('day')而不是.hours(0).minutes(0).seconds(0)。因此,第一行将是:var today = moment().startOf('day')
Jim Geurts

2
如果我们要moment(today)克隆对象,则另一个解决方案是:var tomorrow = today.clone().add(1, 'days')
johntellsall

1
@johntellsall显式克隆而不是隐式,结果相同,但实际上可能更容易阅读!
码头-吕克·Gendreau所言

1
另外,我可以建议以下内容$ltmoment(today).endOf('day')。为了防止第二天的实际结果被包括在内。
greduan

1
moment(today).endOf('day')给出了时间的同一天:23:59:59.999。因此实际上看起来更正确使用$lte,否则在特定时间的对象将被忽略。
leonprou

11

是的,Date对象包含日期和时间,因此将其与仅日期值进行比较是行不通的。

您可以简单地使用$ where运算符通过Javascript布尔表达式来表达更复杂的条件:)

db.posts.find({ '$where': 'this.created_on.toJSON().slice(0, 10) == "2012-07-14"' })

created_on是datetime字段,2012-07-14是指定的日期。

日期应完全为YYYY-MM-DD格式。

注:使用$where谨慎,它会对性能产生影响。


10

你有没有尝试过:

db.posts.find({"created_on": {"$gte": new Date(2012, 7, 14), "$lt": new Date(2012, 7, 15)}})

您将遇到的问题是日期在Mongo中存储为时间戳。因此,要匹配日期,您要求它匹配时间戳。就您而言,我认为您要尝试匹配一天(即特定日期的00:00到23:59)。如果您的日期没有时间存储,那您就可以了。否则,如果gte不起作用,请尝试将您的日期指定为同一天的时间范围(例如,开始= 00:00,结束= 23:59)。

类似的问题


1
这将包括所有比指定日期还年轻的元素,这可能不是OP想要的。考虑像其他答案一样添加“ lt”选项。
BenSower

我认为如果您选择$gtegte它,那就更好了。
杰克·

上面已经很正确地回答了这个问题,但是知道我的回答不对,这使我很困惑,所以我更新了它以解决问题。嘿,已经四年了。大声笑
Michael D Johnson

6

您可以对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'

1

我们遇到了一个与数据库中重复数据有关的问题,其中一个date字段具有多个本应具有1的值。我想我应该添加解决问题的方式以供参考。

我们有一个名为“数据”的集合,其中包含一个数字“值”字段和一个日期“日期”字段。我们有一个我们认为是幂等的过程,但最终在第二次运行中每天增加了2个值:

{ "_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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.