174 votes

MongoDB/Mongoose effectuant des requêtes à une date précise ?

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

J'ai trouvé dans le Cookbook de Mongo que nous pouvons le faire pour une gamme Recherche d'une plage de dates Comme ça :

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

2voto

Rogerio Orioli Points 51

Je le fais avec cette méthode et cela fonctionne bien

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

`
``

2voto

Bhagat Gurung Points 11

Le problème que j'ai rencontré est le filtrage de la date dans le backend, lorsque la date est réglée sur 0 heure, 0 minute, 0 seconde, 0 milliseconde dans le serveur de nœuds, elle est réglée en heure ISO. La date actuelle de 0 heure, 0 minute, 0 seconde, 0 milliseconde du client peut donc varier, ce qui peut donner un jour après ou avant en raison de la conversion de l'heure ISO en fuseau horaire local.

Je les ai corrigés en envoyant l'heure locale du client au serveur.

 // 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()

Et utilisé cette fois pour filtrer les documents en utilisant cette requête

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

1voto

Brett Points 544

Nous avons eu un problème lié à des données dupliquées dans notre base de données, avec un champ de date ayant plusieurs valeurs alors qu'il ne devait en avoir qu'une. J'ai 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 numérique "value" et un champ date "date". Nous avions un processus que nous pensions idempotent, mais qui finissait par ajouter 2 x valeurs par jour au deuxième passage :

{ "_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 d'un seul des deux enregistrements, donc nous avons dû recourir au javascript pour nettoyer la base de données. Notre approche initiale allait être d'itérer à travers les résultats et de supprimer tout champ avec une heure entre 6h et 11h (tous les doublons étaient dans la matinée), mais pendant l'implémentation, a fait un changement. Voici le script utilisé pour le corriger :

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

et l'a ensuite exécuté avec mongo thedatabase fixer_script.js

0voto

abrsh Points 42

Il semble qu'aucune des réponses n'ait fonctionné pour moi. Bien que quelqu'un ait mentionné une petite astuce, j'ai réussi à la faire fonctionner avec le code ci-dessous.

let endDate = startingDate
endDate = endDate + 'T23:59:59';

Model.find({dateCreated: {$gte: startingDate, $lte: endDate}})

startingDate sera la date spécifique avec laquelle vous voulez faire une requête.

J'ai préféré cette solution pour éviter d'installer moment et juste pour passer le startingDate comme "2021-04-01" en facteur.

0voto

user1994 Points 407

Une solution très simple à ce problème est donnée ci-dessous.

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)

Ainsi, le code ci-dessus trouve simplement les enregistrements de la date de début donnée à la date de fin donnée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X