MongoDB / Мангуст запрос на определенную дату?

можно ли запросить конкретную дату ?

Я нашел в Поваренной книге монго, что мы можем сделать это для диапазона запрос диапазона дат Вот так:

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

но возможно ли для конкретной даты ? Это не работает :

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

6 ответов


Это должно работать, если даты, сохраненные в БД, не имеют времени (только год, месяц, день).

вероятность, что нужные вам спастись new Date(), который включает компоненты времени. Чтобы запросить эти времена, вам нужно создать диапазон дат, который включает все моменты в день.

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

для тех из нас, используя момент.js

var moment = require('moment')

var today = moment().startOf('day')
var tomorrow = moment(today).endOf('day')

MyModel.find({
  createdAt: {
    $gte: today.toDate(),
    $lt: tomorrow.toDate()
  }
})

важно: все моменты изменчивы!

tomorrow = today.add(1, 'days') не работает, так как он также мутирует today. Зову moment(today) решает эту проблему косвенно клонирования today.


Да, объект Date дополняет дату и время, поэтому сравнение его только со значением даты не работает.

вы можете просто использовать $, где оператор для выражения более сложного условия с логическим выражением Javascript:)

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

created_on - это поле datetime и 2012-07-14 - указанная дата.

дата должна быть именно в ГГГГ-ММ-ДД.

Примечание: использовать $where скупо, это имеет последствия для производительности.


вы пробовали:

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

проблема, с которой вы столкнетесь, заключается в том, что даты хранятся как метки времени в Mongo. Итак, чтобы соответствовать дате, вы просите ее соответствовать метке времени. В вашем случае я думаю, что вы пытаетесь соответствовать дню (т. е. с 00:00 до 23:59 на конкретную дату). Если ваши даты хранятся без времени, то вы должны быть в порядке. В противном случае попробуйте указать дату в качестве диапазона времени в тот же день (т. е. начало=00: 00, Конец=23: 59) если 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'

У нас была проблема, связанная с дублированными данными в нашей базе данных, с полем даты, имеющим несколько значений, где мы должны были иметь 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")}

нам нужна только 1 из 2 записей, поэтому пришлось прибегнуть к 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