Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does one properly increment many dates in mongoDB?

Not being a particularly strong Javascript guy, I'm having a bit of trouble trying to update a lot of Date objects in Mongo.

It seems that $inc has not yet been implemented for Date objects. So, to try and bump a bunch of dates by a day, I called (something like) this script from bash via mongo myScript.js:

conn = new Mongo();
db   = conn.getDB('myDatabase');

var incrementDates = function() {
  db.blah.find(myQuery).forEach(function(doc) {

    db.blah.update(
       { _id     : doc._id
       , my_date : { $exists : true }
       }
     , { $set : { my_date : new Date(doc.my_date.getTime() + 86400000) }}
    );

  });
}

incrementDates();

The basic idea seems to work well enough in the mongoDB shell:

> var doc = db.blah.findOne(myQuery)
> doc.my_date
ISODate("1962-11-02T23:00:00Z")
> new Date(doc.my_date.getTime() + 86400000);
ISODate("1962-11-03T23:00:00Z")

But not so well in the script:

TypeError: doc.my_date has no properties

So I take it that I'm trying to call getTime on a null somewhere, even though the query in my update should only return documents where my_date exists.

Any ideas as to what's happening here? More importantly: is there a better way to do this?

like image 972
jtobin Avatar asked Sep 12 '13 08:09

jtobin


People also ask

How do I increment in MongoDB?

In MongoDB, the $inc operator is used to increment the value of a field by a specified amount. The $inc operator adds as a new field when the specified field does not exist, and sets the field to the specified amount. The $inc accepts positive and negative value as an incremental amount.

What is the best way to store date in MongoDB?

You can specify a particular date by passing an ISO-8601 date string with a year within the inclusive range 0 through 9999 to the new Date() constructor or the ISODate() function. These functions accept the following formats: new Date("<YYYY-mm-dd>") returns the ISODate with the specified date.

How do I update multiple records in MongoDB?

You can update multiple documents using the collection. updateMany() method. The updateMany() method accepts a filter document and an update document. If the query matches documents in the collection, the method applies the updates from the update document to fields and values of the matching documents.

What is multi option in update in MongoDB?

In MongoDB, you can update multiple documents in the collection using db. collection. updateMany() method. This method updates all the documents in the collection that match the given filter. updateMany() is a mongo shell method, which can update multiple document.


1 Answers

Starting in Mongo 5.0, it's a nice use case for the new $dateAdd aggregation operator:

// { "date" : ISODate("2020-04-05T07:14:17.802Z"), "x" : "y" }
db.collection.updateMany(
  { date : { $exists : true } },
  [{ $set: { date: { $dateAdd: { startDate: "$date", unit: "day", amount: 1 } } } }]
)
// { "date" : ISODate("2020-04-06T07:14:17.802Z"), "x" : "y" }
  • The first part { date : { $exists : true } } is the match query, filtering which documents to update (in our case all documents having the date field).

  • The second part [{ $set: { date: { $dateAdd: { startDate: "$date", unit: "day", amount: 1 } } } }], updates the value of the date field by adding ($dateAdd) 1 (amount) day (unit) to $date (startDate).

like image 78
Xavier Guihot Avatar answered Oct 03 '22 11:10

Xavier Guihot