web-dev-qa-db-fra.com

Insertion et interrogation de date avec MongoDB et Nodejs

J'ai besoin d'aide pour trouver un enregistrement par date dans mongodb et nodejs.

J'ajoute la date à l'objet json dans un script de scraping comme suit:

jsonObj.last_updated = new Date();

Cet objet est inséré dans mongodb. Je peux le voir comme suit:

 "last_updated" : "2014-01-22T14:56:59.301Z"

Ensuite, dans mon script nodejs, je fais un findOne ():

 var jObj = JSON.parse(line.toString());

 collection.findOne(jObj,function(err, doc) {
   if (doc){
     console.log(doc._id);
   } else  {
     console.log('not found');
   }
 });

L'objet n'est pas trouvé. Si je supprime le champ last_updated de l’objet, il est trouvé, c’est là que réside le problème.

Si j'isole le champ comme suit:

collection.findOne({last_updated: '2014-01-22T14:56:59.301Z'},function(err, doc) {
  if (doc){
    console.log(doc._id);
  } else  {
    console.log('not found');
  }
});

Rien ne revient non plus. Qu'est-ce que je fais mal, s'il vous plaît?

35
jeh

Vous devez passer un objet de date et non une chaîne de date.

collection.findOne({last_updated: new Date('2014-01-22T14:56:59.301Z')},function(err, doc) {

Le pilote MongoDB le transformera en ISODate:

{ 
   "_id" : ObjectId("52dfe0c469631792dba51770"), 
   "last_updated" : ISODate('2014-01-22T14:56:59.301Z') 
}

Vérifiez ces questions:

62
Ilan Frumer

Clarifier. Ce qui est important à savoir, c'est que:

  • Oui, vous devez passer un objet Date Javascript.
  • Oui, il faut que ce soit convivial
  • Oui, d'après mon expérience, il est nécessaire de manipuler la date à l'ISO.
  • Oui, travailler avec des dates est généralement un processus fastidieux, et mongo ne fait pas exception

Voici un extrait de code fonctionnel dans lequel nous effectuons un peu de manipulation de date pour nous assurer que Mongo puisse le gérer correctement. Dans cet exemple, j'utilise le module mangouste et je veux des résultats pour les lignes dont l'attribut date est inférieur (c'est-à-dire avant) à la date indiquée comme paramètre myDate.

var inputDate = new Date(myDate.toISOString());
MyModel.find({
    'date': { $lte: inputDate }
})
11
arcseldon

J'ai récemment rencontré le même problème et je voulais ajouter quelques informations supplémentaires.

Vous pouvez insérer des dates de deux manières:

  1. Créé côté serveur nodejs (par exemple dans un script ExpressJS)

exemple: insérer un nouvel objet et le marquer dans le temps

db.collection('mycollection').findOneAndUpdate({'name': req.body.name}, {
  // only "update" if it's an insert, meaning name is not found
  $setOnInsert: {
    'name': req.body.name,
    'date_added': new Date()
  }
}, { 
  upsert: true
}, (err, result) => {
  if(err) return res.send(err);
  res.send(result);
});
  1. Créé côté client à partir de JS puis envoyé sur le réseau en utilisant une API REST dans un objet JSON via une demande POST

exemple:

// Send POST Request here
fetch('addDate', {
  method: 'post',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    'date_added':  new Date()
  })
})

Pour 1. et 2. vous créez les dates à l'aide de la fonction new Date('2014-01-22T14:56:59.301Z') comme expliqué dans les réponses ci-dessus. La différence est que si vous le faites comme dans 1. côté serveur à l'aide du paquet MongoClient, il est stocké sous la forme ISODate('2014-01-22T14:56:59.301Z') dans MongoDB. Si vous le faites comme dans 2. du côté client, il est stocké sous la forme d'une chaîne: '2014-01-22T14:56:59.301Z' Dans MongoDB.

Pour interroger l'objet ISODate, vous devez utiliser new Date('2014-01-22T14:56:59.301Z') ou ISODate('2014-01-22T14:56:59.301Z'). Pour interroger la chaîne, utilisez uniquement la chaîne: '2014-01-22T14:56:59.301Z'

Voici quelques exemples de requêtes utilisant le shell mongo:

Date stockée sous forme de chaîne:

db.mycollection.findOne({date_added {$gte:'2018-06-22T00:07:53.688Z'}})

Cela retourne

{
  "_id" : ObjectId("5b2c3dd90078ce3cd484ef21"),
  "name" : "alfons",
  "date_added" : "2018-06-22T00:07:53.688Z"
}

Date stockée sous ISODate:

db.mycollection.findOne({date_added: {$lte: ISODate('2018-06-26T23:24:37.023Z')}})

ou en utilisant "nouvelle date" à la place:

db.mycollection.findOne({date_added: {$lte: new Date('2018-06-26T23:24:37.023Z')}

Cela retourne:

{
  "_id" : ObjectId("5b2bb21e1954b104e61ff735"),
  "name" : "ceasar",
  "date_added" : ISODate("2018-06-21T14:11:41.323Z")
}
4
Renato