1

I am using mongodb 3.6 and have below validator for the students collection:

rs1:PRIMARY> db.getCollectionInfos({name: 'students'})
[
    {
        "name" : "students",
        "type" : "collection",
        "options" : {
            "validator" : {
                "$jsonSchema" : {
                    "properties" : {
                        "name" : {
                            "bsonType" : "string",
                            "description" : "name"
                        },
                        "age" : {
                            "bsonType" : "int",
                            "minimum" : 10,
                            "maximum" : 30
                        }
                    },
                    "required" : [
                        "name",
                        "age"
                    ],
                    "bsonType" : "object"
                }
            },
            "validationLevel" : "strict",
            "validationAction" : "error"
        },
        "info" : {
            "readOnly" : false,
            "uuid" : BinData(4,"111r7z+rQpGoebZ1jAHO4g==")
        },
        "idIndex" : {
            "v" : 2,
            "key" : {
                "_id" : 1
            },
            "name" : "_id_",
            "ns" : "test.students"
        }
    }
]

it requires two properties name and age. Name must be a string and age must be between 10 and 30. But why does below insert fail?

rs1:PRIMARY> db.students.insert({age: 11, name: 'Mike'})
WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 121,
        "errmsg" : "Document failed validation"
    }
})
  • ,From 3.2 release of MongoDB the idea of document validation was introduced. You have to check the "data type" with valid MongoDB document validation. – Md Haidar Ali Khan Apr 13 '18 at 14:05
1

As I am able to see you are getting the insert writeError with Error code : 121 like that

"nInserted" : 0,
    "writeError" : {
        "code" : 121,
        "errmsg" : "Document failed validation"

As per MongoDB blog documentation of @Jai Hirsch here for MongoDB document validation. Sometimes you want completely free form documents and sometimes you don’t. In the 3.2 release of MongoDB the idea of document validation was introduced. One area I have encountered problems in the past is with dates being inserted using different data types.

Example: (command line notation used for brevity) The first team was using numeric dates:

 db.date.insert({date:20150321}) 

The second team was using string format:

db.date.insert({date:"03/21/2015"})

The third team was using ISO dates:

 db.date.insert({date:new Date('Mar 21, 2015')}) 

The communication issues that lead to this problem is a story for another time, but needless to say a fair amount of data cleanup was required to fix the issue as the primary application that read the data was expecting an ISO date. The code issue was solved by using a shared library that defined the database mapping object. Now let’s take a look at how document validation could be used to solve this problem.

We will create a collection with the following command:

db.createCollection( "date", {
    validator: { date: {$type:"date"}}
} )

With the collection created with the validator one can now only insert using the new Date() format:

db.date.insert({date:new Date('Mar 21, 2015')})

The numeric and string inserts will give the following error:

WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 121,
        "errmsg" : "Document failed validation"
    }
})

likewise almost every developer new to MongoDB will make this "mistake" on the command line like:

db.numbers.insert({number:2})

One would think that they have inserted a document containing the integer number two into the collection, when in fact the document now contains a floating-point value.

I can attest to the pain this can cause (especially if you are using a strongly typed language such as JAVA).

We can use the validator to safeguard against this:

db.createCollection( "numbers", {
    validator: { number: {$type:"int" }}
} )

The preceding insert will now give us the 121 error code and you need to use the NumberInt constructor:

db.numbers.insert({number:NumberInt(2)})
  • 1
    You are on the right track with differences in numeric data types, however the OP's question is about JSON Schema validation (MongoDB 3.6+) and your examples use the older data validation. You could trim this answer down to a more concise requirement to use NumberInt() in the shell since JavaScript's only native numeric type is a double precision floating point. – Stennie Apr 13 '18 at 20:46
  • I'm also curious: what does BOL mean? From usage context I gather it is when you are quoting another source (usually the MongoDB manual), but I haven't seen this abbreviation commonly used elsewhere. In this case you have substantially quoted someone's blog post but haven't clearly delineated which parts of the answer you have written. – Stennie Apr 13 '18 at 20:46
  • @Stennie, Thanks for advice. what does BOL mean? From usage context I gather it is when you are quoting another source (usually the MongoDB manual). Yes , I agree with you. That answer of source part come from "Jai Hirsch", MongoDB Blog post documentation . But the "NumberInt" and "floating point value" validation definition refer to the MongoDB BOL documentation. – Md Haidar Ali Khan Apr 14 '18 at 8:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.