Conversion from string to bson.date

I try to build a rest api using node 14, latest mongodb, latest mongodb node-js driver.
I try to give the simplest example for my present concern:
Let’s consider a database with a collection named posts having the following validation schema:

{
    "jsonSchema": {
        "bsonType": "object",
        "properties": {
            "dateAdded": {
                "bsonType": "date"
            }
        }
    }
}

Now, using a tool like Insomnia or Postman if I try to post the following it will fail the validation:

{
    "dateAdded": "2021-08-11T17:54:14.692Z"
}

Obviously, in json there is no date type, so for this operation to succeed a conversion is needed from string to bson.date. The question is if there is a built-in way in MongoDB to perform this conversion automatically, or do I need to somehow capture the post in backend, to check it’s validation schema and to convert it accordingly?

And, this was just an example, I need to know how this works… for all data types!

Hello @Sorin_GFS,

Obviously, in json there is no date type, so for this operation to succeed a conversion is needed from string to bson.date .

You are correct.

The question is if there is a built-in way in MongoDB to perform this conversion automatically, or do I need to somehow capture the post in backend,…

There is no built-in (or automatic) way to convert string type to bson date type (the type of date data stored in MongoDB). In general, the driver software (in this case the MongoDB NodeJS driver) does the actual conversion to bson type stored in the database. This conversion happens only if you supply the driver with appropriate convertible data type - and for NodeJS / JavaScript applications it is the Date object.

So, create a JavaScript date object from the string input, and pass it to the date field as the value and the validation will get through during inserts and updates.

Thank you for clarifications. So I need to capture the json post and to correct it before sending it to db. For simple fields this is not a hard thing to do, but when comes to updates… things get messy. E.g update filters with operators:

    "filter": {
        "dateAdded": ( "$gt": "2021-08-11T17:54:14.692Z"}
    },
    "update": {
        "dateAdded": "2021-08-11T17:54:14.692Z"
    }

This is just an example, things can get really messy for multiple operators or aggregations… Probably this is the reason why there are no MongoDB rest api’s arround…

Your application code can be something like this (this transformation is required):

let dateStr = "2021-08-11T17:54:14.692Z";
let jsonDoc = {  "dateAdded": new Date(dateStr) };

I know how to convert in javascript, the problem is that through api is transmitted in json format. It was nice if MongoDB could automatically process a json like this:

   { "dateAdded": "'new Date(2021-08-11T17:54:14.692Z)'" }

The date captured in the web app, is of string type and there is no way to tell MongoDB that what is the content of the field (which is a string). It can be any of these:

let fld1 = "Hello world";
let fld2 = "2021-08-11T17:54:14.692Z";

And, both are strings, and there is no way to automatically figure the second field is a date field. Even if you parse the field value and try to figure the content is of date, then there are different formats of dates captured as string and these are to be parsed and converted in a different way. So, the application code handles it using the new Date(dateStr), which does that conversion so that the field value can be stored as bson date. This is also, same case with other MongoDB drivers. For example, in Java you do what is called as mapping using a POJO / Java class to a MongoDB document (where you specify how each field maps, and for a date field you specify the Java’s java.util.Date type and this maps to MogoDB bson date).

I dissagree, there is schema validation, as I wroted in my first post:

@Sorin_GFS, the validation is for the data type being stored in the database - so, it becomes the responsibility of the application to provide the appropriate type data so that can be converted by the driver.

You are correct that the Schema Validation does check that the field was of type string and not a date (and the validation fails).

I dissagree again, the validation can be retrieved from the database and can be used to convert fields based on the retrieved schema. I solved that part, it’s easy, and… the validation schema can be also cached since it doesn’t change often:

This is my function:

    async getValidation() {
        if (!this.isConnected) await this.init();
        const collection = await this.db.listCollections({ name: this.collection }).toArray();
        return { validator: collection[0].options.validator, validationLevel: collection[0].options.validationLevel, validationAction: collection[0].options.validationAction };
    }

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.