$jsonSchema operator in mongodb
Tags: mongodb, jsonschema, validation
Published: 2020-09-09 17:35:12

---
title: $jsonSchema operator in mongodb
published: true
description: All you need to know about $jsonSchema
tags: mongodb, jsonSchema, validation
//cover_image: https://direct_url_to_image.jpg
---

Prior to MongoDB `3.6`, there was no way to define what value(s) a field in a MongoDB document will be (even if we love it's schema-less nature, we might still have that feeling to be able to do something like this), we resolved into using an ODM like [mongoose](https://mongoosejs.com/) to be able to define a schema for a collection.

From MongoDB 3.6 it became possible to define a schema for a collection, but it's not as concise and 100% intuitive with the Mongoose approach.

The `$jsonSchema` is an evaluation operator in MongoDB, that does not only allow one define a schema for a collection, the $jsonSchema operator can also be used to match document(s) that meets a specific structure.

To be able to define a schema for a collection one has to use the `db.createCollection` method


```javascript
db.createCollection("student", {
  validator: {
    $jsonSchema: {
      required: [
        "email",
        "phoneNumber",
        "fullName",
        "dateOfBirth",
        "subjects",
        "address",
      ],
      bsonType: "object",
      properties: {
        email: {
          bsonType: "string",
          description: "Email Address of student",
        },
        phoneNumber: {
          bsonType: "string",
          description: "Phone Number of the student",
        },
        fullName: {
          bsonType: "string",
          description: "student full name",
        },
        dateOfBirth: {
          bsonType: "date",
          description: "Date of Birth of student",
        },
        subjects: {
          enum: ["English", "Mathematics", "Biology", "Government"],
          description: "Value specified does not match the required subject",
        },
        address: {
          bsonType: "object",
          required: ["city", "street"],
          properties: {
            city: {
              bsonType: "string",
              description: "City of the student",
            },
            street: {
              bsonType: "string",
              description: "Street of user",
            },
            houseNumber: {
              bsonType: "int",
              description: "House number of the student",
            },
          },
        },
      },
    },
  },
  validationLevel: "strict",
  validationAction: "error",
});

```


From the above code, you will see the use of `bsonType`, `bsonType` stands for binary json, it's like a superset of json, and it supports various data types such as 64bit integer and regular expression, more information about this [here](https://www.mongodb.com/json-and-bson).

The use of `bsonType` in the above code, is to specify what datatype a field accept, for the `dateOfBirth` the accepted datatype is a date object.

Let's try to insert an empty document and see what happens.

```javascript
db.student.insert({})
```

When you run the above, MongoDB will show you this beautiful error message

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


Now this brings us to the next point, the `required` option, the `required` option is an array of fields that must be exist in the document to be inserted. The validator requires the `email`, `phoneNumber`, `fullName`, `dateOfBirth` , `subjects` and `address` fields to be available when inserting a new document.
In our above example, we tried inserting an empty document, hence we got back that error. Let's correct this


```javascript
db.student.insert({
  email       : "test@example.com",
  phoneNumber : "+234111111",
  fullName    : "Victory Osikwemhe",
  dateOfBirth : new Date("08/08/1996"),
  subjects    : "Physics",
  address     : {
    city      : "Abuja",
    street    : "Ademola Adetokunbo Crescent, Wuse 2"
  }
});
```


Running the above operation in mongo cli, we will also be presented with the previous error, and it's as a result of the wrong value specified to the `subjects` key. This brings us to what `enum` does, `enum` specifies the only values that a particular field is allowed to have, in our $jsonSchema validation object, we have something like this `enum: [ "English", "Mathematics", "Biology", "Government" ]` for the `subjects` field, and it's clear that "Physics" is not among the list, let's correct it by changing "Physics" to a valid value.


```javascript
db.student.insert({
  email       : "test@example.com",
  phoneNumber : "+234111111",
  fullName    : "Victory Osikwemhe",
  dateOfBirth : new Date("08/08/1996"),
  subjects    : "Government",
  address     : {
    city      : "Abuja",
    street    : "Ademola Adetokunbo Crescent, Wuse 2",
    houseNumber : NumberInt(22)
  }
});
```

Everything is fine now.

*They are two options above that controls the behaviour of the $jsonSchema validator*


```javascript
{
  validationLevel: "strict",
  validationAction: "error"
}
```


`$jsonSchema` is also capable of validating update operations also.

The `validationLevel` option specifies how well will MongoDB play with insert and update operation(s). This option only supports three values `strict` , `off` and `moderate`.

`off` does not perform any form of validation on the document that is been inserted or updated

![Security Guard](https://media1.tenor.com/images/a896411a001705014cf9075aae195420/tenor.gif)

`strict` applies the validation rules on all insert and update operation, basically no invalid document will be allowed.

![Hammer on the Head](https://media1.tenor.com/images/b0d270b7c07757cc6c3fb6efc60229e8/tenor.gif)

```javascript
db.student.updateOne({ email: "test@example.com"}, { $set: { dateOfBirth: "08/08/1997" } });
```

Running the above code, the result will be a `Document failed validation` error, because we are trying to update a field that only supports a date object.

`moderate` applies the validation rules on all insert and existing *valid* document in the collection.


The `validationAction` option controls how MongoDB reports the invalid document, it supports two values `error` and `warn`.

The `error` value prevents the invalid document from been inserted in the collection, same applies to trying to update a document with an invalid field.

The `warn` value logs out the error, but still allows the invalid document to be inserted/updated.

The $jsonSchema validator also have support  for many keywords to further specify how a field should be validated.

[$jsonSchema Keywords](https://docs.mongodb.com/manual/reference/operator/query/jsonSchema/index.html#available-keywords) 

The part 2 of this post will be on how to use `$jsonSchema` in query conditions to match documents that meets the specified criteria.


Thanks for reading :)