How to Define a Schema in MongoDB

Tahseen Tauseef Feb 02, 2024
  1. Schema in MongoDB
  2. Considerations in Designing a Schema in MongoDB
  3. Define a Schema in MongoDB
  4. Enforce a Schema Using MongoDB Realm
How to Define a Schema in MongoDB

This article will discuss the MongoDB schema and how to define it.

Schema in MongoDB

The structure and contents of your data are defined by a schema, which is a JSON object. Realm’s BSON schemas, which extend the JSON Schema standard, can be used to design your app’s data model and validate documents whenever they are created, changed, or deleted.

Instead of precise values, schemas represent different types of data. Many built-in schema types are supported by Realm. Primitives like texts, numbers, and structural types such as objects and arrays can be combined to form schemas representing custom object types.

For example, a basic schema for data about cars and some car objects conforming to the schema is given below.

Schema:

{
  "title": "car",
  "required": [
    "_id",
    "year",
    "make",
    "model",
    "kilometers"
  ],
  "properties": {
    "_id": { "bsonType": "objectId" },
    "year": { "bsonType": "string" },
    "make": { "bsonType": "string" },
    "model": { "bsonType": "string" },
    "kilometers": { "bsonType": "number" }
  }
}

Objects:

{
  "_id": ObjectId("5af712eff26b29dc5c51c60f"),
  "year": "2022",
  "make": "Honda",
  "model": "Civic",
  "kilometers": 123
}
{
  "_id": ObjectId("5af714eff24b294c5251cf04"),
  "year": "2016",
  "make": "Honda",
  "model": "City",
  "kilometers": 135794
}

Schemas are the data model specifications for your application. Realm gives you additional tools and services to work with data that conforms to the schema once you’ve defined it.

Many application services in Realm use schemas:

  1. To sync data between realms and MongoDB Atlas, Realm Sync employs schemas. Based on your schemas, it may also develop idiomatic SDK object models for you.
  2. The GraphQL API automatically employs schemas to generate a GraphQL schema that automatically includes types, queries, and mutations. Custom resolvers that reference the types defined by your schemas can be added to your app’s API.
  3. Before and after each request, Data Access Rules ensure that the data conforms to your schema. In addition, Realm prevents or rolls back the entire request if any document fails validation.

Considerations in Designing a Schema in MongoDB

  1. Design your schema according to user requirements.
  2. If you use the objects together, combine them into a single document. Separate them if necessary (but make sure there should not be a need for joins).
  3. Duplicate the data (but limited) because disk space is cheaper than computing time.
  4. Do joins while writing, not on reading.
  5. Optimize your schema for the most frequent use cases.
  6. Do complex aggregation in the schema.

An example to explain this is given below:

Suppose that a client needs a database design for his blog or website and sees the differences between RDBMS and MongoDB schema design. The website has the following requirements.

  1. Every post has a unique title, description, and URL.
  2. Every post can have one or multiple tags.
  3. Every post has the publisher’s name and the total number of likes.
  4. Every post includes user comments and their name, message, data-time, and likes.
  5. On each post, there can be none or more comments.

In the RDBMS schema, the design for the above requirements will have a minimum of three tables.

RDBMS Schema Design

While in MongoDB schema, the design will have one collection post and the following structure:

{
  _id: POST-ID
  title: TITLE-OF-POST,
  description: POST-DESCRIPTION,
  by: POST-BY,
  url: URL-OF-POST,
  tags: [TAG1, TAG2],
  likes: TOTAL-LIKES,
  comments: [
    {
        user: 'COMMENT-BY',
        message: TEXT,
        dateCreated: DATE-TIME,
        like: LIKES
    },
    {
        user: 'COMMENT-BY',
        message: TEXT,
        dateCreated: DATE-TIME,
        like: LIKES
    }
  ]
}

So, in RDBMS, you must combine three tables to display the data; however, in MongoDB, data is only displayed from one collection.

Define a Schema in MongoDB

Additional schemas that specify the type’s attributes can be found in a root-level collection schema. Each root-level schema is an object schema, which looks like this:

{
  "bsonType": "object",
  "title": "<Type Name>",
  "required": ["<Required Field Name>", ...],
  "properties": {
    "<Field Name>": <Schema>
  }
}

The user can use any of the following supported schema types to configure the object’s properties:

  1. Object
  2. Array
  3. String
  4. Boolean
  5. ObjectId
  6. Binary Data
  7. Mixed
  8. Set
  9. Dictionary

Enforce a Schema Using MongoDB Realm

All write operations (inserts, updates, and deletes) on a MongoDB collection are validated against the collection schema by MongoDB Realm.

It also examines each document before and after each request to ensure that all properties are consistent with the schema and no invalid changes are made.

Before committing the write operations to your cluster, Realm checks the results of all document writes and compares them to the schema.

MongoDB Realm delivers an error to the user if the outcome of any write operation in a request does not fit the schema without making any changes to the request.

An example of this is given below. A collection has the following schema:

{
  "title": "person",
  "properties": {
    "_id": {"bsonType": "objectId" },
    "name": {"bsonType": "string" }
    }
}

A user with full access to all fields wishes to change the name field in a specific document. They enquire about the following:

collection.updateOne(
  { "_id": BSON.ObjectId("5ae782e48f25b9dc5c51c4d0") },
  { "$set": { "name": 22 } }
)

The query tries to set the name value to the number 22. Despite this, the schema specifies that the value is a string.

Even if the user received authorization to update the document, MongoDB Realm would reject this write operation because the write result does not adhere to the schema.