MongoDB Projection Operators

Control which fields to include or exclude in results

👁️ What are Projection Operators?

Projection operators control which fields appear in query results. They help you retrieve only the data you need, improving performance and reducing bandwidth usage.


// Get only name and email fields
db.users.find({}, { name: 1, email: 1 })
                                    

Basic Projection

Basic projection uses 1 to include fields and 0 to exclude them. You can't mix inclusion and exclusion except for the _id field.

Include Fields

Show only specified fields

db.users.find({}, { name: 1, age: 1 })

Exclude Fields

Hide specified fields

db.users.find({}, { password: 0 })
🆔

Exclude _id

Remove _id from results

db.users.find({}, { _id: 0, name: 1 })
🎯

Nested Fields

Project nested document fields

db.users.find({}, { "address.city": 1 })

🔹 Include Specific Fields

Use 1 to include only the fields you want. The _id field is included by default unless explicitly excluded.

🔸 Basic Inclusion

// Include only name and email
db.users.find({}, { name: 1, email: 1 })

// Include fields without _id
db.users.find({}, { _id: 0, name: 1, email: 1 })

Full Document:

{ "_id": 1, "name": "Alice", "email": "[email protected]", "age": 25, "password": "secret123" }

With Projection { name: 1, email: 1 }:

{ "_id": 1, "name": "Alice", "email": "[email protected]" }

🔹 Exclude Specific Fields

Use 0 to exclude fields you don't want. All other fields will be included in the results.

🔸 Basic Exclusion

// Exclude password field
db.users.find({}, { password: 0 })

// Exclude multiple sensitive fields
db.users.find({}, { password: 0, ssn: 0, creditCard: 0 })

Full Document:

{ "_id": 1, "name": "Bob", "email": "[email protected]", "password": "secret456" }

With Projection { password: 0 }:

{ "_id": 1, "name": "Bob", "email": "[email protected]" }

🔹 $slice Operator

The $slice operator limits the number of array elements returned in query results. Perfect for pagination or limiting large arrays.

🔸 Slice Array Elements

// Get first 3 comments
db.posts.find(
    { _id: 1 },
    { comments: { $slice: 3 } }
)

// Get last 2 comments
db.posts.find(
    { _id: 1 },
    { comments: { $slice: -2 } }
)

// Skip 2, return 3 comments
db.posts.find(
    { _id: 1 },
    { comments: { $slice: [2, 3] } }
)

Full Document:

{ "_id": 1, "title": "Post", "comments": ["Great!", "Nice", "Awesome", "Cool", "Amazing"] }

With { comments: { $slice: 3 } }:

{ "_id": 1, "title": "Post", "comments": ["Great!", "Nice", "Awesome"] }

🔹 $elemMatch Operator

The $elemMatch operator projects the first array element that matches the specified condition.

🔸 Match Array Elements

// Get first score greater than 80
db.students.find(
    { _id: 1 },
    { 
        name: 1,
        scores: { $elemMatch: { $gt: 80 } }
    }
)

// Get first completed task
db.users.find(
    { _id: 1 },
    {
        name: 1,
        tasks: { $elemMatch: { status: "completed" } }
    }
)

Full Document:

{ "_id": 1, "name": "John", "scores": [65, 75, 85, 95] }

With { scores: { $elemMatch: { $gt: 80 } } }:

{ "_id": 1, "name": "John", "scores": [85] }

🔹 $ Positional Operator

The $ operator projects the first array element that matches the query condition.

🔸 Project Matched Element

// Find and project matching array element
db.students.find(
    { "grades.score": { $gt: 85 } },
    { "grades.$": 1 }
)

// Get specific matched item
db.orders.find(
    { "items.name": "Laptop" },
    { "items.$": 1 }
)

Full Document:

{ "_id": 1, "name": "Alice", "grades": [
    { "subject": "Math", "score": 75 },
    { "subject": "Science", "score": 90 }
]}

Query: { "grades.score": { $gt: 85 } }, Projection: { "grades.$": 1 }:

{ "_id": 1, "grades": [{ "subject": "Science", "score": 90 }] }

🔹 Nested Document Projection

Project specific fields from nested documents using dot notation.

// Project nested fields
db.users.find(
    {},
    { 
        name: 1,
        "address.city": 1,
        "address.country": 1
    }
)

// Project from deeply nested documents
db.orders.find(
    {},
    {
        orderNumber: 1,
        "customer.name": 1,
        "customer.contact.email": 1
    }
)

Full Document:

{ 
    "_id": 1, 
    "name": "John", 
    "address": { 
        "street": "123 Main St", 
        "city": "New York", 
        "country": "USA", 
        "zip": "10001" 
    } 
}

With { name: 1, "address.city": 1, "address.country": 1 }:

{ "_id": 1, "name": "John", "address": { "city": "New York", "country": "USA" } }

🔹 Practical Examples

Real-world projection scenarios:

Example 1: User Profile API

// Return safe user data for public profile
db.users.find(
    { username: "john_doe" },
    {
        _id: 0,
        username: 1,
        name: 1,
        bio: 1,
        avatar: 1,
        followers: { $slice: 10 }
    }
)

Example 2: Product Listing

// Show product summary without full details
db.products.find(
    { category: "Electronics" },
    {
        name: 1,
        price: 1,
        thumbnail: 1,
        rating: 1,
        reviews: { $slice: 3 }
    }
)

Example 3: Blog Post Preview

// Get post preview with limited comments
db.posts.find(
    { published: true },
    {
        title: 1,
        author: 1,
        excerpt: 1,
        publishDate: 1,
        comments: { $slice: 5 },
        tags: 1
    }
).limit(10)

🧠 Test Your Knowledge

Which value includes a field in projection?