How do I convert a property in MongoDB from text to date type?
This code should do it:
> var cursor = db.ClockTime.find()
> while (cursor.hasNext()) {
... var doc = cursor.next();
... db.ClockTime.update({_id : doc._id}, {$set : {ClockInTime : new Date(doc.ClockInTime)}})
... }
I have exactly the same situation as Jeff Fritz.
In my case I have succeed with the following simpler solution:
db.ClockTime.find().forEach(function(doc) {
doc.ClockInTime=new Date(doc.ClockInTime);
db.ClockTime.save(doc);
})
This is a generic sample code in python using pymongo
from pymongo import MongoClient
from datetime import datetime
def fixTime(host, port, database, collection, attr, date_format):
#host is where the mongodb is hosted eg: "localhost"
#port is the mongodb port eg: 27017
#database is the name of database eg : "test"
#collection is the name of collection eg : "test_collection"
#attr is the column name which needs to be modified
#date_format is the format of the string eg : "%Y-%m-%d %H:%M:%S.%f"
#http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior
client = MongoClient(host, port)
db = client[database]
col = db[collection]
for obj in col.find():
if obj[attr]:
if type(obj[attr]) is not datetime:
time = datetime.strptime(obj[attr],date_format)
col.update({'_id':obj['_id']},{'$set':{attr : time}})
for more info : http://salilpa.com/home/content/how-convert-property-mongodb-text-date-type-using-pymongo
Starting Mongo 4.x
:
-
db.collection.update()
can accept an aggregation pipeline, finally allowing the update of a field based on its current value (Mongo 4.2+
). - There is a new
$toDate
aggregation operator (Mongo 4.0
).
Such that:
// { a: "2018-03-03" }
db.collection.update(
{},
[{ $set: { a: { $toDate: "$a" } } }],
{ multi: true }
)
// { a: ISODate("2018-03-03T00:00:00Z") }
-
The first part
{}
is the match query, filtering which documents to update (in this case all documents). -
The second part
[{ $set: { a: { $toDate: "$a" } } }]
is the update aggregation pipeline (note the squared brackets signifying the use of an aggregation pipeline).$set
is a new aggregation operator which in this case replaces the field's value. The replaced value being the field itself concerted to anISODate
object. Note howa
is modified directly based on its own value ($a
). -
Don't forget
{ multi: true }
, otherwise only the first matching document will be updated. Or alternatively one can useupdateMany
instead ofupdate
:db.collection.updateMany(...)
.