Insert field with $currentDate to MongoDB collection in Meteor

36,570

Solution 1

What's the point of having an operator that only works with updates, if that's indeed the case?

$currentDate is an update operator thus you can't use it with the collection.insert method. But when upsert is true it will create a new document when no document matches the query criteria. MongoDB operators tend to follow the Unix philosophy

Do One Thing and Do It Well

So each operator should perform only one task.

Why/when is $currentDate better than new Date?

First I would like to mention that new Date is a JavaScript Date instance.

$currentDate and new Date can be used when you want to update the value of a field to current date but with new Date you need to use another update operator for it to work. For example:

  • Using new Date

    db.collection.update({ "name": "bar" }, { "$set": { "date": new Date() }})
    
  • Using $currentDate

    db.collection.update({ "name": "bar"}, 
        { "$currentDate": { "date": { "$type": date }}}
    )
    

Unlike $currentDate, new Date can be use with the insert method and value can be set to a particular if Date is call with more than on argument.

Solution 2

You can retrieve timestamp from autogenerated "_id" that is created within insert operation.

http://api.mongodb.com/java/current/org/bson/types/ObjectId.html

Just use the method : ObjectId.getTimestamp().

Timestamp granularity is in seconds.

Solution 3

$currentDate when used in the $update construct can be used to insert fields if they do not pre-exist in the document.

Quoting documentation for Mongodb 3.4: Behavior

If the field does not exist, $currentDate adds the field to a document.
Share:
36,570

Related videos on Youtube

Mallory-Erik
Author by

Mallory-Erik

Updated on September 29, 2021

Comments

  • Mallory-Erik
    Mallory-Erik over 2 years

    Not sure how to use $currentDate when inserting a document into a MongoDB collection in Meteor.

    Can this only be used in an update, not an insert? Would seem strange, but I don't see an alternative (other than using new Date instead).

    Example

    Stuff.insert({ 
       owner: Meteor.userId(),
       createdAt: ..., // how to create this field with $currentDate ?
       theStuff: "Some of the good stuff"
    })
    

    Notes / Thoughts / TL,DR

    • Fields can't start with $ operators or, as far as I know, curly braces {}.
    • What's the point of having an operator that only works with updates, if that's indeed the case?
    • Why/when is $currentDate better than new Date?
    • One nice thing, if using Moment.js esp, is that $currentDate is entered in ISO 8601 format.
    • Is the answer to do some kind of upsert from the start? If so, could this have unintended consequences?
  • Mestre San
    Mestre San about 8 years
    Still. If you have a distributed application connecting to your replicaSet / sharded cluster inserting a lot of docs per second you would like a createdAt field to be consistent and using the $currentDate on the Insert would be a better solution. If you don't have a high insertion volume upsert and insert might be the same for you but they are actually not. Upsert is slower and when you use new Date you are getting the date from the client machine not from the database server, thus you are vulnerable to inconsistencies when it comes to sorting by createdAt.
  • styvane
    styvane about 8 years
    @MestreSan $currentDate only works with updateOne or updateMany. Not with insert. Perhaps you mean update when you say insert in comment.
  • Mestre San
    Mestre San almost 8 years
    No @user3100115, I know that $currentDate only woks with updates and not with insert. What I meant was that would be a good feature to have the $currentDate operator available on inserts. Just like any RDMS has the now function available on inserts for example for one to use on a field createdAt to know the precise moment your record was created.
  • Gian Franco Zabarino
    Gian Franco Zabarino almost 8 years
    @MestreSan Checkout my answer to this question, it may be a solution for what you're stating: stackoverflow.com/a/37061284/2911851
  • Eric Rini
    Eric Rini about 7 years
    Is it possible to use $currentDate in conjunction with the $setOnInsert operator. This would allow an upsert\insert to set a "created" date, without upsert\update overwriting it each time.