Skip to main content

MongoDB Data Types

Introduction

MongoDB, as a document-oriented NoSQL database, provides support for various data types to accommodate different kinds of information in your applications. Understanding these data types is crucial for designing effective data models and writing efficient queries.

Unlike traditional relational databases with rigid schemas, MongoDB offers flexibility in document structure, allowing fields to hold different types of data. This flexibility is one of MongoDB's key advantages, but it also means developers need to understand the available data types to use them appropriately.

In this tutorial, we'll explore the various data types supported by MongoDB, how to use them, and their practical applications.

Basic Data Types

MongoDB supports a rich set of data types that can be used in documents. Let's start by exploring the most commonly used ones:

String

Strings are the most common data type used for storing text data. In MongoDB, strings are UTF-8 encoded.

js
// Example of a document with string fields
{
_id: ObjectId("60a7d45a9f8e8c001f3c0a1b"),
name: "John Doe",
email: "[email protected]",
address: "123 MongoDB Ave."
}

Number

MongoDB supports several numeric types:

  1. Integer (32-bit)
  2. Integer (64-bit)
  3. Decimal (128-bit)
  4. Double (64-bit)
js
// Example using different number types
{
_id: ObjectId("60a7d45a9f8e8c001f3c0a1c"),
product_id: 1001, // 32-bit integer
price: NumberDecimal("29.99"), // Decimal128
quantity_in_stock: NumberLong(15000), // 64-bit integer
rating: 4.7 // Double
}
tip

Use NumberDecimal() for financial calculations to avoid floating-point precision issues that can occur with double precision numbers.

Boolean

Boolean values represent either true or false.

js
{
_id: ObjectId("60a7d45a9f8e8c001f3c0a1d"),
product_name: "Wireless Earbuds",
in_stock: true,
is_featured: false
}

Date

MongoDB stores dates as 64-bit integers representing milliseconds since the Unix epoch (January 1, 1970). The Date type makes it easy to store and query based on timestamps.

js
// Creating a document with date fields
{
_id: ObjectId("60a7d45a9f8e8c001f3c0a1e"),
user_id: "u1001",
created_at: new Date(),
last_login: ISODate("2023-06-15T10:30:00Z")
}

When inserting dates in the mongo shell:

js
// Current date and time
db.users.insertOne({
name: "Alice",
registration_date: new Date()
})

// Specific date
db.users.insertOne({
name: "Bob",
registration_date: ISODate("2023-01-15T08:00:00Z")
})
note

MongoDB stores dates in UTC by default. When displaying dates, your driver or application might convert them to local time zones.

Null

Null represents the absence of a value or an undefined state.

js
{
_id: ObjectId("60a7d45a9f8e8c001f3c0a1f"),
title: "MongoDB Basics",
subtitle: null,
author: "Jane Smith"
}

Complex Data Types

Array

Arrays in MongoDB can contain values of different types and are indexed by position starting from 0.

js
{
_id: ObjectId("60a7d45a9f8e8c001f3c0a20"),
username: "tech_enthusiast",
interests: ["MongoDB", "JavaScript", "Cloud Computing"],
scores: [95, 87, 92]
}

You can query for specific array elements:

js
// Find users interested in MongoDB
db.users.find({ interests: "MongoDB" })

// Find users with a score of 95
db.users.find({ scores: 95 })

Object/Embedded Document

MongoDB allows you to embed documents within documents, creating complex nested structures.

js
{
_id: ObjectId("60a7d45a9f8e8c001f3c0a21"),
name: "Sarah Johnson",
contact: {
email: "[email protected]",
phone: "123-456-7890",
address: {
street: "456 Database Lane",
city: "Query Town",
zip: "54321"
}
}
}

To query embedded documents, use dot notation:

js
// Find users in Query Town
db.users.find({ "contact.address.city": "Query Town" })

ObjectId

ObjectId is a 12-byte identifier typically used as the _id field in documents. It consists of:

  • 4 bytes: timestamp
  • 5 bytes: random value
  • 3 bytes: incrementing counter
js
{
_id: ObjectId("60a7d45a9f8e8c001f3c0a22"),
product_name: "MongoDB T-shirt"
}

You can extract the timestamp from an ObjectId:

js
const id = ObjectId("60a7d45a9f8e8c001f3c0a22");
const timestamp = id.getTimestamp();
console.log(timestamp); // Outputs the creation time

Binary Data and Code Types

Binary Data

Binary data (BinData) is used for storing binary information like images, files, or encrypted data.

js
{
_id: ObjectId("60a7d45a9f8e8c001f3c0a23"),
filename: "profile.jpg",
content_type: "image/jpeg",
file_data: BinData(0, "ZmFrZSBiaW5hcnkgZGF0YQ==")
}

JavaScript Code

MongoDB can store JavaScript code which can be helpful for storing functions or expressions.

js
{
_id: ObjectId("60a7d45a9f8e8c001f3c0a24"),
name: "calculateTotal",
code: function(items) {
return items.reduce((total, item) => total + item.price, 0);
}
}

Special Data Types

Regular Expression

MongoDB supports regular expressions for pattern matching in queries.

js
// Document with a RegExp field
{
_id: ObjectId("60a7d45a9f8e8c001f3c0a25"),
validation_pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
}

// Using RegExp in a query
db.users.find({ email: /gmail\.com$/ }) // Find users with Gmail addresses

Timestamp

Timestamp is an internal MongoDB type used primarily for replication and sharding operations.

js
{
_id: ObjectId("60a7d45a9f8e8c001f3c0a26"),
operation_timestamp: Timestamp(1620000000, 1)
}

MinKey and MaxKey

These special types always compare as the lowest and highest possible BSON values, respectively.

js
{
_id: ObjectId("60a7d45a9f8e8c001f3c0a27"),
range_start: MinKey(),
range_end: MaxKey()
}

Practical Examples

Example 1: E-commerce Product Catalog

Let's design a product document that uses multiple data types:

js
db.products.insertOne({
_id: ObjectId(),
name: "Wireless Bluetooth Headphones",
sku: "TECH-1234",
price: NumberDecimal("89.99"),
discount_price: NumberDecimal("79.99"),
in_stock: true,
stock_count: NumberInt(250),
categories: ["Electronics", "Audio", "Wireless"],
specifications: {
color: "Black",
connectivity: "Bluetooth 5.0",
battery_life: "20 hours",
weight_grams: 255
},
reviews: [
{
user_id: ObjectId("60a7d45a9f8e8c001f3c0a28"),
rating: 5,
comment: "Great sound quality!",
posted_date: new Date("2023-05-15")
},
{
user_id: ObjectId("60a7d45a9f8e8c001f3c0a29"),
rating: 4,
comment: "Good but battery could be better",
posted_date: new Date("2023-05-18")
}
],
last_updated: new Date(),
limited_edition: null,
warranty_years: NumberInt(2)
})

Example 2: User Profile with Address History

This example demonstrates tracking user address history:

js
db.users.insertOne({
_id: ObjectId(),
username: "jsmith",
email: "[email protected]",
password_hash: BinData(0, "aGFzaGVkIHBhc3N3b3JkIGRhdGE="),
profile: {
first_name: "John",
last_name: "Smith",
date_of_birth: new Date("1985-07-15"),
profile_image: null
},
address_history: [
{
address_line: "123 Main St",
city: "Boston",
state: "MA",
zip: "02108",
country: "USA",
from_date: new Date("2020-01-01"),
to_date: new Date("2021-06-30"),
is_verified: true
},
{
address_line: "456 Park Ave",
city: "New York",
state: "NY",
zip: "10022",
country: "USA",
from_date: new Date("2021-07-01"),
to_date: null, // Current address
is_verified: true
}
],
account_created: new Date(),
last_login: ISODate("2023-06-15T14:25:00Z"),
settings: {
theme: "dark",
notifications_enabled: true,
two_factor_auth: false
}
})

Example 3: Working with Arrays in MongoDB

Let's explore how to perform operations with arrays:

js
// Adding a document with an array
db.courses.insertOne({
name: "MongoDB Fundamentals",
topics: ["CRUD Operations", "Aggregation", "Indexes", "Data Modeling"],
difficulty_level: 2
})

// Adding elements to an array
db.courses.updateOne(
{ name: "MongoDB Fundamentals" },
{ $push: { topics: "Data Types" } }
)

// Adding multiple elements at once
db.courses.updateOne(
{ name: "MongoDB Fundamentals" },
{ $push: { topics: { $each: ["Replication", "Sharding"] } } }
)

// Querying for a specific array element
db.courses.find({ topics: "Indexes" })

// Querying for documents that have arrays with multiple specific values
db.courses.find({ topics: { $all: ["Indexes", "Data Modeling"] } })

// Removing an element from an array
db.courses.updateOne(
{ name: "MongoDB Fundamentals" },
{ $pull: { topics: "Data Types" } }
)

Data Type Considerations

Schema Design Best Practices

When designing your MongoDB schema, consider these data type best practices:

  1. Use appropriate number types:

    • Use NumberDecimal for currency and financial calculations
    • Use NumberInt (32-bit) for smaller numbers
    • Use NumberLong (64-bit) for larger integers
  2. Be consistent with date formats:

    • Always store dates using the MongoDB Date type
    • Avoid storing dates as strings
  3. Arrays and embedded documents:

    • Arrays should contain related items
    • Embedded documents are best for information that is always accessed together
    • Be cautious about unbounded arrays that can grow indefinitely
  4. ObjectIds:

    • Let MongoDB generate ObjectIds for the _id field when possible
    • You can create custom ObjectIds when necessary, but ensure they're unique

Data Type Conversion

MongoDB allows for implicit type conversion in some scenarios, but it's best to be explicit:

js
// Example of type conversions
db.conversions.insertOne({
string_num: "42",
actual_num: 42
})

// This will match both documents due to type conversion
db.conversions.find({ actual_num: 42 }) // Matches
db.conversions.find({ actual_num: "42" }) // Also matches!

// For strict type matching, use $type
db.conversions.find({ actual_num: { $type: "int" } })

Schema Validation

MongoDB allows you to enforce data types using schema validation:

js
db.createCollection("products", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["name", "price", "stock_count"],
properties: {
name: {
bsonType: "string",
description: "must be a string and is required"
},
price: {
bsonType: "decimal",
description: "must be a decimal and is required"
},
stock_count: {
bsonType: "int",
minimum: 0,
description: "must be an integer >= 0 and is required"
},
categories: {
bsonType: "array",
items: {
bsonType: "string"
}
}
}
}
}
})

With this validation, MongoDB will reject documents that don't meet the specified data type requirements.

Summary

MongoDB supports a wide range of data types to accommodate various application needs:

  1. Basic types: String, Number (integer, decimal, double), Boolean, Date, and Null
  2. Complex types: Array, Object (embedded document), and ObjectId
  3. Special types: Binary Data, JavaScript Code, Regular Expression, Timestamp, MinKey, and MaxKey

Understanding these data types is crucial for effective schema design, efficient querying, and correct data manipulation in MongoDB. By choosing the appropriate data types, you can optimize storage, improve query performance, and ensure data consistency in your applications.

Additional Resources

Exercises

  1. Create a database for a blog with collections for posts, comments, and users. Use appropriate data types for each field.

  2. Design a schema for a library management system. Include books, authors, and borrowing records using MongoDB data types.

  3. Create a collection with schema validation that enforces specific data types for a customer record including name (string), age (integer), and purchase history (array of embedded documents).

  4. Write a query that uses the $type operator to find all documents where a specific field is a particular data type.

  5. Create a function that accepts arbitrary user input and converts it to the appropriate MongoDB data type before storing it in a collection.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)