Welcome to the first lesson of the "Schemas and Relations" course! This is the second course in our MongoDB learning path. In the first course, you mastered the fundamental CRUD operations. Now, we will focus on data modeling — the crucial step of structuring your data when building a project.
In this specific lesson, we'll explore the data types available in MongoDB. Understanding these data types will enable you to choose the right one for your needs, optimizing both performance and data integrity. We'll cover basic JSON data types and advanced BSON data types. Additionally, we'll discuss document limitations in terms of document size and nesting depth.
MongoDB stores data using the BSON format, which is an extension of JSON. Consequently, MongoDB supports all the data types available in JSON. Let’s explore these essential JSON types:
- String: Used to store textual data.
- Array: Can hold multiple values, which can be of various data types.
- Object: Represents a document within a document.
- Boolean: Holds
true
orfalse
values. - Null: Represents the absence of a value.
- Floating-point number: The default type for all numbers in MongoDB, with or without decimal points.
Here is a code snippet demonstrating the insertion of a document containing various JSON data types:
JavaScript1use library_db 2 3db.books.insertOne({ 4 title: "Harry Potter and the Goblet of Fire", // String 5 author: "J.K. Rowling", // String 6 genre: "Fantasy", // String 7 published_year: 2000, // Floating-point number (default for integers) 8 ratings: [5, 5, 4, 5], // Array (of Integers) 9 info: { // Object (Nested Document) 10 pages: 600, 11 publisher: "Bloomsbury" 12 }, 13 best_seller: true, // Boolean 14 out_of_print: null, // null 15 price: 25.99 // Floating-point number 16})
As mentioned earlier, BSON format extends JSON format and includes a few additional data types: ObjectId
, Date
, Timestamp
, NumberLong
, NumberDecimal
, among others. For an in-depth look at BSON data types, refer to the BSON Specification and MongoDB's BSON Data Types.
ObjectId is a unique identifier commonly used for the _id
field in MongoDB documents. The _id
field is reserved as a primary key, and its value must be unique within the collection, is immutable, and can be of any type except an array. By default, MongoDB automatically generates this field if you don't explicitly define it. However, you can also specify its value manually when needed, for instance, by using ObjectId
:
JavaScript1use library_db 2 3// Using auto-generated ObjectId 4db.books.insertOne( { 5 title: "Harry Potter and the Goblet of Fire", 6 author: "J.K. Rowling" 7}) 8 9// Specifying ObjectId explicitly 10db.books.insertOne({ 11 _id: ObjectId("507f1f77bcf86cd799439011"), 12 title: "1984", 13 author: "George Orwell" 14}) 15 16// Creating ObjectId without constructor parameter 17db.books.insertOne({ 18 _id: new ObjectId(), 19 title: "The Hobbit", 20 author: "J.R.R. Tolkien" 21})
To manually define an ObjectId, you can use the ObjectId
constructor. By passing a 24-character hexadecimal string as a parameter to the constructor, you can create a specific ObjectId. If you create an ObjectId
without passing any parameters, MongoDB will automatically generate a new unique identifier. Note that using a non-24-character hexadecimal string as a parameter will cause an error.
Date and Timestamp types in MongoDB handle date and time data.
- Date: Stores specific dates and times in JavaScript Date format.
- Timestamp: Stores a specific moment in time, usually for logging changes.
Examples of using Date and Timestamp:
JavaScript1use library_db 2 3// Using the Date type without parameters (current date and time) 4db.books.insertOne({ 5 title: "Harry Potter and the Goblet of Fire", 6 created_on: new Date(), // Date without parameters 7 author: "J.K. Rowling" 8}) 9 10// Using the Date type with only the date 11db.books.insertOne({ 12 title: "1984", 13 published_date: new Date("1949-06-08"), 14 author: "George Orwell" 15}) 16 17// Using the Date type with date and time 18db.books.insertOne({ 19 title: "The Hobbit", 20 created_on: new Date("1937-09-21T08:00:00Z"), 21 author: "J.R.R. Tolkien" 22}) 23 24// Using the Timestamp type 25db.books.insertOne({ 26 title: "The Catcher in the Rye", 27 created_at: Timestamp(), 28 author: "J.D. Salinger" 29})
By default, the MongoDB shell treats all numbers as floating-point values. For example, 2
and 2.39
are stored as floating-point numbers using the NumberDouble
type. For integers beyond the NumberInt
range, such as 4000000000
, MongoDB uses the NumberLong
type.
However, you can explicitly specify different numeric types instead of relying on the automatically inferred type:
- NumberLong: Stores 64-bit integers for very large numbers. Its constructor accepts a number as a string:
NumberLong("2090845886852")
. - NumberDecimal: Supports high-precision decimal values, crucial for financial calculations. Its constructor accepts a number as a string:
NumberDecimal("12.1274856338")
. - NumberInt: Stores 32-bit integers, e.g.,
NumberInt(1988)
.
Examples of using NumberLong
, NumberDecimal
, and NumberInt
:
JavaScript1use library_db 2 3// Using various numeric types 4db.inventory.insertOne({ 5 product_id: "B201", 6 stock: NumberLong("1000000000"), // NumberLong 7 price_avg: NumberDecimal("99.12345678901234567890123456"), // NumberDecimal 8 weight: 15.75, // NumberDouble 9 rating: NumberInt(5), // NumberInt 10 supplier: "Precision Supplies Inc." 11})
Now that you know which data types you can use to store your data, it's time to talk about some limitations of MongoDB documents concerning document size and nesting:
-
Document Size Limit: Individual documents in MongoDB have a maximum size limit of 16 megabytes (MB). This limit ensures better performance and stability. If you need to store large amounts of data, consider splitting the data across multiple documents or using GridFS, a specification for storing and retrieving large files.
-
Nesting Limit: MongoDB imposes a limit on the depth of nested documents. A single document can be nested up to 100 levels deep. Exceeding this limit can lead to performance degradation and difficulties in data manipulation. It's generally advisable to avoid deep nesting and to keep document structures as flat as possible for simplicity and efficiency.
In this lesson, we've introduced the diverse set of data types available in MongoDB, including JSON types and BSON types. Furthermore, we touched upon the limitations of MongoDB documents, including the maximum document size and nesting depth. These data types and limitations form the foundation for structuring your data efficiently. In the upcoming practices, you'll get to apply these concepts and solidify your understanding. Happy learning!