Inserting and Querying Date with MongoDB and Nodejs
Asked Answered
Q

5

50

I need some help finding a record by date in mongodb and nodejs.

I add the date to the json object in a scraping script as follows:

jsonObj.last_updated = new Date();

This object is inserted into mongodb. I can see it as follows:

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

Then in my nodejs script I do a findOne():

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

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

The object is not found. If I remove the last_updated field from the object it is found so it is definitely where the problem is.

If I isolate the field as follows:

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

Nothing comes back either. What am I doing wrong please?

Quarrelsome answered 22/1, 2014 at 15:8 Comment(1)
new Date(Date.now()).toISOString()Wrongdoing
D
82

You need to pass a date object and not a date string.

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

The MongoDB driver will transform it into ISODate:

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

Check these questions:

Defame answered 22/1, 2014 at 15:21 Comment(4)
Combining with momentjs Items.find({sellingState: "Active", endTime: {$lt: new Date(moment().subtract(1, 'day').toISOString())}}, {limit: 10})Irreclaimable
To store now use new Date without the parensSpermatocyte
Yup. Do not use new Date().toISOString() when inserting into MongoDB database (instead just use new Date()) because MongDB already does the conversion for you and .toISOString() will make .find() operators or $gte operators on the database failImpatient
Using new Date without the parentheses (using Node 12.18 and mongo 3.4.1) gives me the same result in the document (a UTC ISODate) as using it with the parentheses, i.e. new Date()Septennial
S
14

To clarify. What is important to know is that:

  • Yes, you have to pass a Javascript Date object.
  • Yes, it has to be ISODate friendly
  • Yes, from my experience getting this to work, you need to manipulate the date to ISO
  • Yes, working with dates is generally always a tedious process, and mongo is no exception

Here is a working snippet of code, where we do a little bit of date manipulation to ensure Mongo can handle it correctly. In this example, I am using mongoose module and want results for rows whose date attribute is less than (ie. before) the date given as myDate param.

var inputDate = new Date(myDate.toISOString());
MyModel.find({
    'date': { $lte: inputDate }
})
Sextodecimo answered 30/7, 2014 at 15:14 Comment(2)
how does the myDate param look like ? Is it the string 'Mon Feb 29 2016 21:04:59 GMT+0100 (CET)' ?Provenience
I believe this is incorrect and made the same mistake which caused errors in my existing database. Do not use new Date().toISOString() when inserting into MongoDB database (instead just use new Date()) because MongDB already does the conversion for you and .toISOString() will make .find() operators or $gte operators on the database failImpatient
T
7

I recently ran into the same issue and I wanted to add some additional info.

You can insert dates in two ways:

  1. Created on the nodejs server side (e.g. in a ExpressJS script)

example: insert a new object and time stamp it

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. Created on the client side from JS and then sent over the wire using a REST API in a JSON object via a POST request

example:

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

For 1. and 2. you create the dates using the new Date('2014-01-22T14:56:59.301Z') function as explained in the answers above. The difference is that if you do it as in 1. on the server side using the MongoClient package it is stored as a ISODate('2014-01-22T14:56:59.301Z') in MongoDB. If you do it as in 2. on the client side it is stored as a String: '2014-01-22T14:56:59.301Z' in MongoDB.

To query the ISODate object you need to use new Date('2014-01-22T14:56:59.301Z') or ISODate('2014-01-22T14:56:59.301Z') To query the string you use just the string: '2014-01-22T14:56:59.301Z'

Here are some query samples using the mongo shell:

Date stored as String:

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

This returns

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

Date stored as ISODate:

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

or using "new Date" instead:

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

This returns:

{
  "_id" : ObjectId("5b2bb21e1954b104e61ff735"),
  "name" : "ceasar",
  "date_added" : ISODate("2018-06-21T14:11:41.323Z")
}
Tycoon answered 27/6, 2018 at 1:6 Comment(0)
U
1

add Default key in Schema and value to Date.now()

Ugh answered 16/11, 2019 at 6:45 Comment(2)
How do you add a default key in the Schema?Assortment
publishedAt:{ type:Date, default:Date.now() }Ugh
B
-1

If your using timestamps data to query. EG : "createdAt" : "2021-07-12T16:06:34.949Z"

const start  = req.params.id; //2021-07-12
const data = await Model.find({
            "createdAt": {
              '$gte': `${start}T00:00:00.000Z`,
              '$lt': `${start}T23:59:59.999Z`
            }
          });
console.log(data);

it will show the data of particular date .i.,e in this case. "2021-07-12"

Brinkema answered 13/7, 2021 at 12:19 Comment(1)
Hard coding time in an ISO string is simply not an answer to OPs question.Ellett

© 2022 - 2024 — McMap. All rights reserved.