web-dev-qa-db-fra.com

MongoDB/Mongoose interroge-t-il à une date précise?

Est-il possible d'interroger pour une date spécifique?

J'ai trouvé dans le livre de recettes mongo que nous pouvons le faire pour une plage Interrogation pour une plage de dates

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

Mais est-ce possible pour une date précise? Cela ne fonctionne pas:

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

Cela devrait fonctionner si les dates que vous avez enregistrées dans la base de données n'ont pas de temps (seulement année, mois, jour).

Il est probable que les dates que vous avez enregistrées étaient new Date(), ce qui inclut les composants de temps. Pour interroger ces heures, vous devez créer une plage de dates incluant tous les moments de la journée.

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

Pour ceux qui utilisent Moment.js

const moment = require('moment')

const today = moment().startOf('day')

MyModel.find({
  createdAt: {
    $gte: today.toDate(),
    $lte: moment(today).endOf('day').toDate()
  }
})

Important: tous les moments sont mutables !

tomorrow = today.add(1, 'days') ne fonctionne pas puisqu'il change également today. L'appel de moment(today) résout ce problème en clonant implicitement today.

93
Pier-Luc Gendreau

As-tu essayé:

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

Le problème que vous allez rencontrer est que les dates sont stockées sous forme d'horodatage dans Mongo. Donc, pour faire correspondre une date, vous lui demandez de faire correspondre un horodatage. Dans votre cas, je pense que vous essayez de faire correspondre un jour (à savoir, de 00h00 à 23h59 à une date précise). Si vos dates sont stockées sans heure, tout devrait bien se passer. Sinon, essayez de spécifier votre date comme plage horaire le même jour (c.-à-d. Début = 00: 00, fin = 23: 59) si le gte ne fonctionne pas.

question similaire

6
Michael D Johnson

Oui, l'objet Date complète la date et l'heure, aussi sa comparaison avec la valeur de date ne fonctionne pas. 

Vous pouvez simplement utiliser l'opérateur $ where pour exprimer une condition plus complexe avec une expression booléenne Javascript :)

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

created_on est le champ datetime et 2012-07-14 est la date spécifiée.

La date doit être exactement au format YYYY-MM-DD.

Remarque: Utilisez $where avec parcimonie, cela a des conséquences sur les performances.

5
Faisal Hasnain

Vous pouvez utiliser l'approche suivante pour la méthode API pour obtenir des résultats d'un jour spécifique:

# [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'
4
Daniel Kmak

Nous avions un problème lié aux données dupliquées dans notre base de données, avec un champ de date comportant plusieurs valeurs où nous étions censés avoir 1. Nous avons pensé ajouter la façon dont nous avons résolu le problème pour référence.

Nous avons une collection appelée "data" avec un champ "valeur" numérique et un champ date "date". Nous avons eu un processus que nous pensions idempotent, mais nous avons fini par ajouter 2 valeurs x par jour lors de la deuxième exécution:

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

Nous n'avons besoin que de 1 des 2 enregistrements, nous avons donc dû recourir au javascript pour nettoyer la base de données. Notre approche initiale consistait à parcourir les résultats et à supprimer tout champ avec une heure comprise entre 6h et 11h (tous les doublons étaient le matin), mais lors de la mise en œuvre, un changement a été opéré. Voici le script utilisé pour résoudre ce problème:

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;
    }
}

puis exécuté avec mongo thedatabase fixer_script.js

0
Brett