'Add time to $currentDate in $set statement

I am trying to perform 2 operations in one findOneAndUpdate():

  • Update date in one field lastUpdatedTimestamp, set it to current date (this one works fine in my statement),
  • Update date in other field expiryTimestamp, by adding 1 day to $currentDate (I couldn't find a way to achieve it so I'm trying to $add 1 day to the the value read from the above field lastUpdatedTimestamp) - (I can't make this one work).

    findOneAndUpdate(
        {"_id":123}, 
        { $currentDate: {"lastUpdatedTimestamp":true}, $set: {"expiryTimestamp": {$add: ["$lastUpdatedTimestamp", 24*60*60000]}}}
    )
    

Here's the error I'm receiving: { "ok" : 0.0, "errmsg" : "The dollar ($) prefixed field '$add' in 'expiryTimestamp.$add' is not valid for storage.", "code" : 52 }

Is it even possible? I'd appreciate your help.



Solution 1:[1]

You can use the setDate() method to set the "expiryTimestamp" value.

db.collection.updateOne(
    { "_id": 123 },  
    { "$set": { 
        "lastUpdatedTimestamp": new Date(),  
        "expiryTimestamp": new Date().setDate(new Date().getDate() + 1) 
    }}
)

You don't need to use findOneAndUpdate unless you want to return the new or old document.

Solution 2:[2]

The marked answer is wrong in the sense that using new Date() will not use database timestamp which is important if your server and database hosted on different region and also count network time for sending data. To correctly do this, use $currentDate like this:

db.collection.findOneAndUpdate({_id: 123 }, {
   $set: { /** update doc here **/ },
   $currentDate: { lastUpdatedTimestamp: true} 
});

Similarly using updateOne

db.collection.updateOne({_id: 123 }, {
   $set: { /** update doc here **/ },
   $currentDate: { lastUpdatedTimestamp: true} 
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 styvane
Solution 2 Ashish Rawat