I want to convert a date stored as a string in my MongoDB collection to the ISODate format using the updateMany operation.
I’ve encountered errors with the approaches I’ve tried so far.
1 st Approach
db.collection.updateMany( { QCDate: { $exists: true } }, [ { $set: { QCDate: { $toDate: { $dateFromString: { dateString: "$QCDate" } } } } } ] )
Error :- node:572942) UnhandledPromiseRejectionWarning: MongoError: Wrong type for ‘u’. Expected a object, got a array.
2 nd Approach
db.collection.updateMany( { QCDate: { $exists: true } },{ $set: { QCDate: { $toDate: { $dateFromString: { dateString: "$QCDate" } } } } } )
error :- (node:570001) UnhandledPromiseRejectionWarning: MongoError: The dollar ($) prefixed field ‘$toDate’ in ‘QCDate.$toDate’ is not valid for storage.
2
Answers
$dateFromString and $toDate both will stop the operation upon the first error, when it fails to convert the given string into a date object. This is what happens in this case. Request you may first assess the data, and take a call on how to deal with the erroneous documents. The following sample documents and action log may give more details on it.
Sample documents
Action log
First of all, check for the erroneous documents. Please note that the following query does not stop on error. This is achieved by OnError. It means on failing to convert a given document, the value given on OnError will be provided. This is useful to identify the erroneous documents. In the sample case, there is one such document. This query filters only such documents and displays it with _id and the old date value.
The above query results will be helpful to assess the documents. And take a call on how to deal with it. In the sample case, there is only one non-convertible document. This shall be corrected by the following query.
Now when we run the query in step 1, it will not yield any documents. As an optional check, the following query can also be run. It would count the number of types in this key and show the count against each type. Ideally it should produce only date type and the count should be as per the documents in the collection. This makes sure that the conversion process is complete and the key has only date type values.
Request you may assess your collection based on the output of such a query discussed above. And see how many documents are failing to convert. By seeing the volume, you will be able to take a call whether a manual correction is possible or not. Once such documents are corrected, your first query itself will be sufficient to complete the job. Please note the following modification in it, $toDate and $dateFromString essentially do the same, therefore only one would be enough.
Note: In case there are many records found for correction, it may require further analysis on the erroneous documents to achieve the possible automation. However, the basic nature of the process required remains the same – data correction.
Some of your data do not have a date string. Apart from that
{ $toDate: { $dateFromString:
is redundant.$dateFromString
returns aDate
value, there is no reason to convert aDate
again into aDate
.Check field for
string
type, then you could also run update multiple times: