InterviewPitch
MongoDB interview questions

MongoDB Interview Questions with Answers

Most Asked MongoDB Interview Questions for Database Engineers and Developers

100+ QuestionsDetailed AnswersCode ExamplesUpdated for 2026

Introduction

MongoDB is a leading NoSQL document database that provides high performance, scalability, and flexibility for modern applications. This page compiles the most frequently asked MongoDB interview questions – from basic CRUD operations and data types to advanced topics like aggregation, indexing, sharding, replication, change streams, transactions, and performance optimisation – essential for backend developers, database administrators, and data engineers.

Why MongoDB?

  • Document‑oriented – stores data as JSON‑like documents (BSON)
  • Schema‑flexible – adapts to changing data models easily
  • Horizontally scalable – sharding for large datasets
  • High performance – optimized for read/write operations
  • Rich query language – powerful aggregation and geospatial queries
  • Enterprise‑ready – ACID transactions, security, and monitoring

Most Asked MongoDB Interview Questions

Beginner
1. What is MongoDB?

MongoDB is a NoSQL document database that stores data in flexible, JSON-like documents. It is designed for scalability, performance, and ease of development.

  • Document-oriented: Stores data as JSON-like documents
  • Schema-less: No predefined schema required
  • Scalable: Horizontal scaling with sharding
  • High performance: Indexing and query optimization
  • Rich queries: Powerful query language and aggregation
mongodb
// Hello World in MongoDB (using mongosh)
print("Hello, World!");

// Or using the mongo shell
db.runCommand({ ping: 1 });
Beginner
2. How to declare variables in MongoDB?

In the mongo shell (mongosh), variables are declared using var, let, or const like JavaScript.

  • var: Global variable (function-scoped)
  • let: Block-scoped variable
  • const: Read-only constant
  • Dynamic typing: Variables can hold any type
  • Shell variables: print() to display
mongodb
// Variables in MongoDB (mongosh)
var mutableVar = "Hello";  // Mutable variable
let immutableVar = "World"; // Block-scoped variable
const constantVar = "Constant"; // Read-only variable

// Type inference
var inferred = 42;

// Display
print(mutableVar);
print(immutableVar);
print(inferred);

// Using shell
var name = "Alice";
print("Hello " + name);
Beginner
3. What are the data types in MongoDB?

MongoDB supports various BSON data types including strings, numbers, booleans, dates, arrays, objects, and ObjectId.

  • String: UTF-8 string
  • Number: Double, Int32, Int64
  • Boolean: true/false
  • Date: ISODate
  • Array: List of values
  • Object: Embedded document
  • ObjectId: 12-byte unique identifier
  • Null: Represents null value
mongodb
// Data Types in MongoDB
// String
var str = "Hello MongoDB";

// Number (Double)
var doubleNum = 3.14;

// Number (Int32)
var intNum = NumberInt(10);

// Number (Long)
var longNum = NumberLong(100);

// Boolean
var isActive = true;
var isInactive = false;

// Date
var date = new Date();

// Null
var nullValue = null;

// Array
var arr = [1, 2, 3, 4, 5];

// Object/Embedded Document
var person = {
    name: "Alice",
    age: 25,
    city: "NYC"
};

// ObjectId
var id = ObjectId();

// Binary Data
var binaryData = BinData(0, "base64encoded");

// Regular Expression
var regex = /pattern/;

// Type checking
typeof intNum; // "number"
Beginner
4. How to define functions in MongoDB?

Functions in MongoDB are defined using JavaScript syntax. They can be used in the shell, in $where queries, or as stored functions.

  • Basic: function name(params)
  • Default parameters: function greet(name = "Guest")
  • Arrow functions: (x) => x * 2
  • Stored functions: db.system.js.insert()
  • $function: Aggregation operator (4.4+)
mongodb
// Functions in MongoDB (mongosh)
// Basic function
function add(a, b) {
    return a + b;
}

// Function with default parameters
function greet(name = "Guest") {
    return "Hello, " + name + "!";
}

// Function with multiple return values (using object)
function divide(a, b) {
    return {
        quotient: Math.floor(a / b),
        remainder: a % b
    };
}

// Higher-order function
function operate(a, b, operation) {
    return operation(a, b);
}

// Lambda expression (arrow function)
var multiply = (a, b) => a * b;

// Anonymous function
var square = function(x) { return x * x; };

// Usage
print(add(5, 3));
print(greet("Alice"));
var result = divide(10, 3);
print(result.quotient);
print(result.remainder);
print(operate(6, 7, multiply));
Beginner
5. What are arrays in MongoDB?

Arrays in MongoDB can store multiple values of any type, including nested documents and arrays.

  • Creation: [1, 2, 3]
  • Access: array[0] (0-indexed)
  • Modification: array[2] = 10
  • Operations: push, pop, map, filter
  • Query operators: $in, $all, $elemMatch
mongodb
// Arrays in MongoDB
// Array creation
var numbers = [1, 2, 3, 4, 5];
var strings = ["Apple", "Banana", "Orange"];
var mixed = [1, "Hello", 3.14];

// Access and modify
numbers[2]; // Access element (0-indexed)
numbers[2] = 10; // Modify element

// Array operations
numbers.length;
numbers.push(6); // Add element
numbers.pop(); // Remove last element

// Iteration
for (var num of numbers) {
    print(num);
}

// Array methods
var doubled = numbers.map(x => x * 2);
var filtered = numbers.filter(x => x > 2);
var sum = numbers.reduce((a, b) => a + b, 0);

// Display
print(doubled);
print(filtered);
print(sum);
Beginner
6. What are collections in MongoDB?

Collections are groups of documents, similar to tables in relational databases. They are created implicitly when inserting documents.

  • Creation: db.createCollection("name")
  • Insert: db.collection.insertOne()
  • Find: db.collection.find()
  • Update: db.collection.updateOne()
  • Delete: db.collection.deleteOne()
  • Capped collections: Fixed-size collections
mongodb
// Collections in MongoDB
// Collections are created implicitly when inserting data

// Insert documents
db.users.insertOne({
    name: "Alice",
    age: 25,
    city: "NYC"
});

db.users.insertMany([
    { name: "Bob", age: 30, city: "LA" },
    { name: "Charlie", age: 35, city: "Chicago" }
]);

// Find documents
db.users.find(); // All documents
db.users.findOne(); // First document

// Query with filter
db.users.find({ age: { $gt: 25 } });

// Update documents
db.users.updateOne(
    { name: "Alice" },
    { $set: { age: 26 } }
);

// Delete documents
db.users.deleteOne({ name: "Bob" });
db.users.deleteMany({ age: { $gt: 30 } });

// Count documents
db.users.countDocuments({ age: { $gt: 25 } });

// Display all
db.users.find().pretty();
Beginner
7. What are documents in MongoDB?

Documents are the basic units of data in MongoDB. They are JSON-like objects with key-value pairs.

  • Structure: { key: value }
  • Nested documents: { address: { city: "NYC" } }
  • Arrays: { hobbies: ["reading", "gaming"] }
  • BSON types: Extended JSON types
  • Field names: Cannot contain '.' or start with '$'
mongodb
// Documents (Data Classes) in MongoDB
// MongoDB documents are JSON-like objects

// Basic document
var person = {
    name: "Alice",
    age: 25,
    city: "Unknown"
};

// Nested document
var person2 = {
    name: "Bob",
    age: 30,
    address: {
        street: "123 Main St",
        city: "LA",
        zip: "90001"
    }
};

// Array of documents
var person3 = {
    name: "Charlie",
    age: 35,
    hobbies: ["reading", "gaming", "hiking"]
};

// Insert document
db.people.insertOne(person);
db.people.insertOne(person2);
db.people.insertOne(person3);

// Query nested fields
db.people.find({ "address.city": "LA" });

// Query array
db.people.find({ hobbies: "gaming" });
Beginner
8. What is schema validation in MongoDB?

Schema validation allows enforcing document structure rules using JSON Schema. It's optional but recommended for data integrity.

  • Validation: validator: { $jsonSchema: {...} }
  • Required fields: required: ["name", "email"]
  • Types: bsonType: "string"
  • Patterns: pattern: "^.+@.+$"
  • Enums: enum: ["active", "inactive"]
mongodb
// Schema Validation in MongoDB
// MongoDB is schema-less, but validation can be added

// Create collection with validation
db.createCollection("users", {
    validator: {
        $jsonSchema: {
            bsonType: "object",
            required: ["name", "email"],
            properties: {
                name: {
                    bsonType: "string",
                    description: "Name is required"
                },
                email: {
                    bsonType: "string",
                    pattern: "^.+@.+$",
                    description: "Email must be valid"
                },
                age: {
                    bsonType: "int",
                    minimum: 0,
                    maximum: 150
                },
                status: {
                    enum: ["active", "inactive", "pending"],
                    description: "Status must be one of the enum values"
                }
            }
        }
    }
});

// Insert with validation
db.users.insertOne({
    name: "Alice",
    email: "alice@example.com",
    age: 25,
    status: "active"
});
Beginner
9. What is null safety in MongoDB?

MongoDB uses null and undefined to represent missing values. Various operators help handle null values safely.

  • Null: { field: null }
  • Existence check: $exists
  • Null check: { field: { $type: 10 } }
  • $ifNull: Default value in aggregation
  • $cond: Conditional handling
mongodb
// Null Safety in MongoDB
// MongoDB uses null and undefined

// Null values
db.users.insertOne({
    name: "Alice",
    email: null,  // Explicit null
    age: undefined // Undefined field
});

// Query for null
db.users.find({ email: null });

// Check for existence
db.users.find({ age: { $exists: true } });

// Check for null or missing
db.users.find({
    $or: [
        { email: null },
        { email: { $exists: false } }
    ]
});

// Using $type to check
db.users.find({ email: { $type: 10 } }); // 10 = null type

// Default values using $ifNull (aggregation)
db.users.aggregate([
    {
        $project: {
            name: 1,
            email: {
                $ifNull: ["$email", "No email provided"]
            }
        }
    }
]);
Beginner
10. What are query operators in MongoDB?

Query operators provide powerful filtering capabilities. They include comparison, logical, element, and evaluation operators.

  • Comparison: $eq, $gt, $lt, $in
  • Logical: $and, $or, $not
  • Element: $exists, $type
  • Evaluation: $regex, $expr
  • Array: $all, $elemMatch, $size
mongodb
// Control Flow in MongoDB
// MongoDB queries use operators for control flow

// Comparison operators
db.users.find({ age: { $eq: 25 } });  // Equal to
db.users.find({ age: { $gt: 25 } });  // Greater than
db.users.find({ age: { $gte: 25 } }); // Greater than or equal
db.users.find({ age: { $lt: 25 } });  // Less than
db.users.find({ age: { $lte: 25 } }); // Less than or equal
db.users.find({ age: { $ne: 25 } });  // Not equal

// Logical operators
db.users.find({
    $and: [
        { age: { $gte: 20 } },
        { age: { $lte: 30 } }
    ]
});

db.users.find({
    $or: [
        { city: "NYC" },
        { city: "LA" }
    ]
});

db.users.find({
    $nor: [
        { status: "inactive" }
    ]
});

db.users.find({
    $not: { age: { $lt: 18 } }
});

// Conditional expression (aggregation)
db.users.aggregate([
    {
        $project: {
            name: 1,
            status: {
                $cond: {
                    if: { $gte: ["$age", 18] },
                    then: "Adult",
                    else: "Minor"
                }
            }
        }
    }
]);
Beginner
11. What are references in MongoDB?

References are used for relationships between documents. They can be manual references (using ObjectId) or DBRef.

  • Manual reference: { userId: ObjectId("...") }
  • DBRef: { $ref: "collection", $id: ObjectId("...") }
  • $lookup: Join collections in aggregation
  • Referencing: Store references, not embedded data
  • Resolution: Use $lookup to resolve references
mongodb
// Classes and Inheritance in MongoDB
// MongoDB doesn't have classes, but uses inheritance patterns

// Single Collection Inheritance
db.animals.insertMany([
    {
        _type: "Animal",
        name: "Generic",
        sound: "Animal sound"
    },
    {
        _type: "Dog",
        name: "Rex",
        breed: "German Shepherd",
        sound: "Woof!"
    }
]);

// Query by type
db.animals.find({ _type: "Dog" });

// Document references (Manual Reference)
var dogId = ObjectId();
db.dogs.insertOne({
    _id: dogId,
    name: "Rex",
    breed: "German Shepherd"
});

db.owners.insertOne({
    name: "Alice",
    dogId: dogId
});

// Query with reference
db.owners.aggregate([
    {
        $lookup: {
            from: "dogs",
            localField: "dogId",
            foreignField: "_id",
            as: "dog"
        }
    }
]);
Beginner
12. What are fields in MongoDB?

Fields are the key-value pairs in MongoDB documents. They can store any BSON data type and can be nested.

  • Field names: Strings, cannot contain '.'
  • Field values: Any BSON type
  • Nested fields: {"address.city": "NYC"}
  • Field projection: Include/exclude fields
  • Field validation: Using schema validation
mongodb
// Properties/Fields in MongoDB
// Fields are defined in documents

// Basic fields
db.users.insertOne({
    name: "Alice",
    age: 25,
    email: "alice@example.com",
    isActive: true,
    createdAt: new Date()
});

// Computed fields (using aggregation)
db.users.aggregate([
    {
        $addFields: {
            fullName: {
                $concat: ["$firstName", " ", "$lastName"]
            },
            ageInDays: {
                $multiply: ["$age", 365]
            }
        }
    }
]);

// Field validation using schema
db.createCollection("validatedUsers", {
    validator: {
        $jsonSchema: {
            properties: {
                name: { bsonType: "string" },
                age: { bsonType: "int", minimum: 0 }
            }
        }
    }
});

// Field projection
db.users.find({}, { name: 1, age: 1, _id: 0 });

// Field existence
db.users.find({ email: { $exists: true } });
Intermediate
13. What are stored functions in MongoDB?

Stored functions are JavaScript functions stored in the system.js collection. They can be called using db.eval().

  • Storage: db.system.js.insertOne()
  • Execution: db.eval("functionName()")
  • Use cases: Complex calculations, data transformation
  • Limitations: Performance overhead, security concerns
  • Alternatives: Use aggregation or application code
mongodb
// Static Methods in MongoDB
// MongoDB uses stored JavaScript functions

// Stored function (server-side)
db.system.js.insertOne({
    _id: "calculateAge",
    value: function(birthYear) {
        return new Date().getFullYear() - birthYear;
    }
});

// Stored function with multiple operations
db.system.js.insertOne({
    _id: "processUser",
    value: function(userData) {
        var user = {
            name: userData.name,
            age: userData.birthYear ? 
                 new Date().getFullYear() - userData.birthYear : 
                 null,
            createdAt: new Date(),
            status: "active"
        };
        return user;
    }
});

// Call stored function
var age = db.eval("calculateAge(1990)");

// Stored procedure-like function
db.system.js.insertOne({
    _id: "createUser",
    value: function(name, email) {
        return db.users.insertOne({
            name: name,
            email: email,
            createdAt: new Date()
        });
    }
});
Intermediate
14. How to handle exceptions in MongoDB?

Exceptions in MongoDB can be handled using try-catch blocks in the shell or application code.

  • try-catch: try catch (error)
  • Validation errors: Schema validation failures
  • Duplicate key errors: Unique index violations
  • Network errors: Connection issues
  • Bulk operations: Handle partial failures
mongodb
// Exception Handling in MongoDB
// Using try-catch in mongosh

// Try-catch block
try {
    var result = db.users.insertOne({
        name: "Alice",
        age: "invalid" // Wrong type
    });
    print(result);
} catch (error) {
    print("Error: " + error.message);
}

// Custom error handling
function safeInsert(collection, document) {
    try {
        var result = collection.insertOne(document);
        return { success: true, result: result };
    } catch (error) {
        return { 
            success: false, 
            error: error.message 
        };
    }
}

// Using with validation
try {
    db.validatedUsers.insertOne({
        name: "Bob",
        age: -5 // Will fail validation
    });
} catch (error) {
    print("Validation error: " + error.message);
}

// Bulk operation with error handling
var bulk = db.users.initializeUnorderedBulkOp();
bulk.insert({ name: "Alice" });
bulk.insert({ name: "Bob" });

try {
    var result = bulk.execute();
    print("Success: " + result.nInserted);
} catch (error) {
    print("Bulk error: " + error.message);
}
Intermediate
15. What are lambda expressions in MongoDB?

Lambda expressions (arrow functions) are used in the mongo shell and in $function aggregation operator.

  • Syntax: (x) => x * 2
  • Array methods: map, filter, reduce
  • $function: Use JavaScript in aggregation
  • MapReduce: Use functions for map and reduce
  • Performance: Use aggregation instead when possible
mongodb
// Lambda Expressions in MongoDB
// Using arrow functions in mongosh

// Basic lambda
var square = (x) => x * x;

// Lambda with multiple parameters
var add = (a, b) => a + b;

// Higher-order functions
function operate(x, y, operation) {
    return operation(x, y);
}

// Array methods with lambdas
var numbers = [1, 2, 3, 4, 5];
var doubled = numbers.map(x => x * 2);
var filtered = numbers.filter(x => x > 2);
var sum = numbers.reduce((a, b) => a + b, 0);

// Aggregation with lambda-like operators
db.users.aggregate([
    {
        $project: {
            name: 1,
            isAdult: {
                $cond: {
                    if: { $gte: ["$age", 18] },
                    then: true,
                    else: false
                }
            }
        }
    }
]);

// MapReduce with functions
db.users.mapReduce(
    function() { emit(this.age, 1); },
    function(key, values) { return Array.sum(values); },
    { out: "ageCount" }
);
Intermediate
16. What are scope functions in MongoDB?

Scope functions like forEach, map, and reduce allow iterating and transforming data in the shell.

  • forEach: cursor.forEach(function(doc) )
  • map: cursor.map(function(doc) )
  • Aggregation: $project, $addFields
  • $function: Custom JavaScript in aggregation
  • Apply: Array.apply(null, { length: n })
mongodb
// Scope Functions in MongoDB
// Using functions and blocks in mongosh

// let - execute block
function processUser(user) {
    if (user) {
        let name = user.name;
        let age = user.age;
        print("Name: " + name);
        user.age = 26;
        return user;
    }
}

// Using with forEach
db.users.find().forEach(function(user) {
    print("User: " + user.name);
});

// Using map
var names = db.users.find().map(function(user) {
    return user.name;
});

// Using $project for transformation
db.users.aggregate([
    {
        $project: {
            name: 1,
            age: 1,
            ageInDays: { $multiply: ["$age", 365] }
        }
    }
]);

// take-if equivalent
function takeIf(condition, value) {
    return condition(value) ? value : null;
}

// Usage
var adult = takeIf(function(age) { return age >= 18; }, 25);
Intermediate
17. What are extension functions in MongoDB?

MongoDB doesn't have extension functions directly, but you can create wrapper functions and use aggregation operators.

  • Wrapper functions: Custom JavaScript functions
  • Aggregation operators: $regexMatch, $type
  • $function: Custom JavaScript in aggregation
  • Stored functions: system.js
  • Application code: Implement extensions in drivers
mongodb
// Extension Functions in MongoDB
// MongoDB doesn't have extension functions directly
// Using wrapper functions and aggregation

// String extensions
function isEmail(str) {
    return /^.+@.+$/.test(str);
}

function addPrefix(str, prefix) {
    return prefix + str;
}

// Numeric extensions
function isEven(n) {
    return n % 2 === 0;
}

function isOdd(n) {
    return n % 2 !== 0;
}

// Array extensions
function secondOrNull(arr) {
    return arr.length >= 2 ? arr[1] : null;
}

// Using with queries
db.users.find({
    $where: "isEmail(this.email)"
});

// Aggregation with custom functions
db.users.aggregate([
    {
        $project: {
            name: 1,
            emailValid: {
                $regexMatch: {
                    input: "$email",
                    regex: "^.+@.+$"
                }
            }
        }
    }
]);
Intermediate
18. What are field aliases in MongoDB?

Field aliases in MongoDB are created using $project in aggregation. They allow renaming fields in output.

  • $project: newName: "$oldName"
  • Computed fields: fullName: { $concat: [...] }
  • View creation: Virtual collections with aliases
  • Renaming: $addFields with $mergeObjects
  • Projection: Include/exclude original fields
mongodb
// Type Aliases in MongoDB
// MongoDB doesn't have type aliases
// Using field aliases and projections

// Field aliases using $project
db.users.aggregate([
    {
        $project: {
            userName: "$name",
            userAge: "$age",
            userEmail: "$email"
        }
    }
]);

// Alias for complex fields
db.users.aggregate([
    {
        $project: {
            fullName: {
                $concat: ["$firstName", " ", "$lastName"]
            },
            ageCategory: {
                $cond: {
                    if: { $gte: ["$age", 18] },
                    then: "Adult",
                    else: "Minor"
                }
            }
        }
    }
]);

// View creation (virtual collection)
db.createView("activeUsers", "users", [
    { $match: { status: "active" } }
]);

// Using with find
db.activeUsers.find();

// Rename fields in output
db.users.find().forEach(function(user) {
    var newUser = {
        userName: user.name,
        userAge: user.age
    };
    printjson(newUser);
});
Intermediate
19. What are inline functions in MongoDB?

Inline functions can be used in $where queries, $function, or as stored functions in system.js.

  • $where: $where: "this.age > 18"
  • $function: $function: { body: function() {...}, args: [...] }
  • Stored functions: db.system.js.insert()
  • Performance: Use aggregation when possible
  • Security: Avoid $where in production
mongodb
// Inline Functions in MongoDB
// MongoDB doesn't have inline functions like Kotlin
// Using server-side JavaScript functions

// Stored function
db.system.js.insertOne({
    _id: "measureTime",
    value: function(fn) {
        var start = new Date().getTime();
        fn();
        var end = new Date().getTime();
        return end - start;
    }
});

// Using stored function
var time = db.eval("measureTime(function() { sleep(1000); })");
print("Time: " + time + "ms");

// Function in query
db.users.find({
    $where: function() {
        return this.age >= 18 && this.age <= 65;
    }
});

// Inline validation
db.users.find({
    $expr: {
        $and: [
            { $gte: ["$age", 18] },
            { $lte: ["$age", 65] }
        ]
    }
});

// Type checking using $type
db.users.find({ age: { $type: "int" } });
Intermediate
20. What are higher-order functions in MongoDB?

Higher-order functions in MongoDB are implemented through aggregation pipeline stages, array operators, and JavaScript functions.

  • Aggregation stages: $project, $group, $match
  • Array operators: $map, $filter, $reduce
  • $facet: Multiple aggregations
  • $lookup: Join collections
  • Function composition: Chaining stages
mongodb
// Higher-Order Functions in MongoDB
// Using functions in aggregation pipeline

// Function composition in aggregation
db.users.aggregate([
    {
        $match: { age: { $gte: 18 } }
    },
    {
        $project: {
            name: 1,
            ageInDays: { $multiply: ["$age", 365] }
        }
    },
    {
        $sort: { age: -1 }
    }
]);

// Custom aggregation functions
db.users.aggregate([
    {
        $facet: {
            adults: [
                { $match: { age: { $gte: 18 } } },
                { $count: "count" }
            ],
            minors: [
                { $match: { age: { $lt: 18 } } },
                { $count: "count" }
            ]
        }
    }
]);

// Function that returns a function (using JavaScript)
function getMultiplier(factor) {
    return function(x) {
        return x * factor;
    };
}

var double = getMultiplier(2);
print(double(5));

// Using with array methods
var numbers = [1, 2, 3, 4, 5];
var processed = numbers
    .filter(x => x > 2)
    .map(x => x * 2)
    .reduce((a, b) => a + b, 0);
print(processed);
Advanced
21. What is the aggregation pipeline in MongoDB?

The aggregation pipeline is a framework for data processing and transformation. It consists of stages that process documents sequentially.

  • Stages: $match, $group, $project
  • Processing: Documents flow through stages
  • Performance: Use indexes and early filtering
  • Complex operations: $lookup, $unwind
  • Output: $out, $merge
mongodb
// Aggregation Pipeline in MongoDB
// The aggregation pipeline is MongoDB's powerful data processing framework

// Basic pipeline
db.users.aggregate([
    { $match: { age: { $gte: 18 } } },
    { $group: { _id: "$city", count: { $sum: 1 } } },
    { $sort: { count: -1 } }
]);

// Multiple stages
db.orders.aggregate([
    {
        $match: {
            status: "completed",
            date: { $gte: ISODate("2023-01-01") }
        }
    },
    {
        $group: {
            _id: "$customerId",
            totalSpent: { $sum: "$amount" },
            orderCount: { $sum: 1 }
        }
    },
    {
        $lookup: {
            from: "customers",
            localField: "_id",
            foreignField: "_id",
            as: "customer"
        }
    },
    {
        $unwind: "$customer"
    },
    {
        $project: {
            customerName: "$customer.name",
            totalSpent: 1,
            orderCount: 1
        }
    }
]);

// $facet for multiple aggregations
db.orders.aggregate([
    {
        $facet: {
            totalRevenue: [
                { $group: { _id: null, total: { $sum: "$amount" } } }
            ],
            byStatus: [
                { $group: { _id: "$status", count: { $sum: 1 } } }
            ],
            byCustomer: [
                { $group: { _id: "$customerId", total: { $sum: "$amount" } } },
                { $sort: { total: -1 } },
                { $limit: 10 }
            ]
        }
    }
]);
Advanced
22. What are change streams in MongoDB?

Change streams provide real-time notifications of data changes. They are used for event-driven architectures and monitoring.

  • Watch: db.collection.watch()
  • Events: insert, update, delete, replace
  • Resume tokens: Resume from interruption
  • Filters: Match specific operations
  • Full document: fullDocument: "updateLookup"
mongodb
// Change Streams in MongoDB
// Change streams allow real-time notification of database changes

// Watch a collection
var changeStream = db.users.watch();

// Watch with pipeline
var changeStream = db.users.watch([
    {
        $match: {
            operationType: { $in: ["insert", "update"] }
        }
    }
]);

// Process changes
changeStream.on("change", function(change) {
    print("Change detected!");
    printjson(change);
});

// Watch with resume token
var resumeToken = null;
var changeStream = db.users.watch([], { 
    resumeAfter: resumeToken 
});

// Watch entire database
var changeStream = db.watch();

// Watch with full document
var changeStream = db.users.watch([], {
    fullDocument: "updateLookup"
});

// Stop watching
changeStream.close();

// Example: Real-time notification
db.users.watch([
    {
        $match: {
            operationType: "insert"
        }
    }
]).on("change", function(change) {
    print("New user added: " + change.fullDocument.name);
});
Advanced
23. How to resume change streams?

Change streams can be resumed using resume tokens or timestamps. This ensures no data is missed during interruptions.

  • Resume token: resumeAfter
  • Start time: startAtOperationTime
  • Token storage: Persist token for recovery
  • Error handling: Resume on errors
  • Multiple streams: Different operations
mongodb
// Change Streams with Resume in MongoDB
// Change streams can resume from a point in time

// Get resume token
var changeStream = db.users.watch();
var resumeToken = null;

changeStream.on("change", function(change) {
    resumeToken = change._id;
    print("Change detected, token saved");
});

// Resume from token
var changeStream = db.users.watch([], {
    resumeAfter: resumeToken
});

// Resume from specific time
var startTime = new Date("2023-01-01T00:00:00Z");
var changeStream = db.users.watch([], {
    startAtOperationTime: Timestamp(startTime.getTime() / 1000, 0)
});

// Multiple change streams
var insertStream = db.users.watch([
    { $match: { operationType: "insert" } }
]);

var updateStream = db.users.watch([
    { $match: { operationType: "update" } }
]);

// Error handling
try {
    var changeStream = db.users.watch();
    changeStream.on("change", function(change) {
        // Process change
    });
} catch (error) {
    print("Change stream error: " + error.message);
}
Advanced
24. What are transactions in MongoDB?

MongoDB supports multi-document ACID transactions for replica sets and sharded clusters. They provide atomicity for multiple operations.

  • Session: db.getMongo().startSession()
  • Start: session.startTransaction()
  • Commit: session.commitTransaction()
  • Abort: session.abortTransaction()
  • Retry: Handle transient errors
mongodb
// Transactions in MongoDB
// MongoDB supports multi-document ACID transactions

// Start a session
var session = db.getMongo().startSession();

// Start transaction
session.startTransaction();

try {
    var users = session.getDatabase("test").users;
    var orders = session.getDatabase("test").orders;

    // Operations
    users.updateOne(
        { _id: "user123" },
        { $inc: { balance: -100 } }
    );

    orders.insertOne({
        userId: "user123",
        amount: 100,
        status: "pending"
    });

    // Commit transaction
    session.commitTransaction();
    print("Transaction committed successfully");

} catch (error) {
    // Abort on error
    session.abortTransaction();
    print("Transaction aborted: " + error.message);

} finally {
    session.endSession();
}

// Transaction with retry
function runTransactionWithRetry() {
    var session = db.getMongo().startSession();
    session.startTransaction();

    try {
        // Operations
        session.commitTransaction();
    } catch (error) {
        if (error.hasOwnProperty("errorLabels") && 
            error.errorLabels.includes("TransientTransactionError")) {
            // Retry transaction
            runTransactionWithRetry();
        } else {
            session.abortTransaction();
            throw error;
        }
    } finally {
        session.endSession();
    }
}
Advanced
25. What are indexes in MongoDB?

Indexes improve query performance by reducing the number of documents scanned. They are essential for efficient queries.

  • Single field: db.collection.createIndex({ field: 1 })
  • Compound: { field1: 1, field2: -1 }
  • Unique: { unique: true }
  • Text: { content: "text" }
  • TTL: { expireAfterSeconds: 3600 }
mongodb
// Indexing in MongoDB
// Indexes improve query performance

// Create single field index
db.users.createIndex({ name: 1 });

// Create compound index
db.users.createIndex({ name: 1, age: -1 });

// Create unique index
db.users.createIndex({ email: 1 }, { unique: true });

// Create text index
db.articles.createIndex({ content: "text" });

// Create geospatial index
db.locations.createIndex({ location: "2dsphere" });

// Create partial index
db.users.createIndex(
    { age: 1 },
    { partialFilterExpression: { age: { $gte: 18 } } }
);

// Create TTL index
db.sessions.createIndex(
    { createdAt: 1 },
    { expireAfterSeconds: 3600 }
);

// List indexes
db.users.getIndexes();

// Drop index
db.users.dropIndex("name_1");

// Explain query plan
db.users.find({ name: "Alice" }).explain("executionStats");

// Index usage
db.users.find({ name: "Alice", age: 25 }).hint({ name: 1, age: -1 });
Advanced
26. What is sharding in MongoDB?

Sharding distributes data across multiple servers for horizontal scaling. It provides high availability and performance for large datasets.

  • Shard key: sh.shardCollection("db.collection", { key: 1 })
  • Hashed sharding: sh.shardCollection("db.collection", { key: "hashed" })
  • Zones: Data distribution by region
  • Chunks: Data partitions
  • Balancer: Distributes chunks evenly
mongodb
// Sharding in MongoDB
// Sharding distributes data across multiple servers

// Enable sharding for database
sh.enableSharding("myDatabase");

// Shard a collection
sh.shardCollection("myDatabase.users", { _id: "hashed" });

// Shard by range
sh.shardCollection("myDatabase.orders", { customerId: 1 });

// Compound shard key
sh.shardCollection("myDatabase.orders", { 
    customerId: 1, 
    orderDate: -1 
});

// Hashed shard key
sh.shardCollection("myDatabase.products", { productId: "hashed" });

// Add shard
sh.addShard("shard1.example.com:27017");
sh.addShard("shard2.example.com:27017");

// Shard status
sh.status();

// Check shard distribution
db.users.getShardDistribution();

// Zone sharding
sh.addShardToZone("shard1", "US");
sh.addShardToZone("shard2", "EU");

// Tag range
sh.updateZoneKeyRange(
    "myDatabase.users",
    { country: "US" },
    { country: "US" },
    "US"
);
Advanced
27. What is replication in MongoDB?

Replication provides high availability and data redundancy through replica sets. It maintains multiple copies of data.

  • Replica set: rs.initiate()
  • Primary: Accepts writes
  • Secondaries: Replicate data
  • Arbiter: Voting only
  • Read preference: readPref("secondary")
mongodb
// Replication in MongoDB
// Replication provides high availability and data redundancy

// Replica set configuration
rs.initiate({
    _id: "rs0",
    members: [
        { _id: 0, host: "localhost:27017", priority: 2 },
        { _id: 1, host: "localhost:27018", priority: 1 },
        { _id: 2, host: "localhost:27019", priority: 0, arbiterOnly: true }
    ]
});

// Add member to replica set
rs.add("localhost:27020");

// Remove member
rs.remove("localhost:27020");

// Reconfigure replica set
rs.reconfig({
    _id: "rs0",
    members: [
        { _id: 0, host: "localhost:27017", priority: 2 },
        { _id: 1, host: "localhost:27018", priority: 1 },
        { _id: 2, host: "localhost:27019", priority: 0 }
    ]
});

// Check status
rs.status();

// Check isMaster
db.isMaster();

// Force primary election
rs.stepDown();

// Set read preference
db.getMongo().setReadPref("secondaryPreferred");

// Read from secondary
db.users.find().readPref("secondary");

// Write concern
db.users.insertOne(
    { name: "Alice" },
    { writeConcern: { w: "majority" } }
);
Advanced
28. What are data modeling patterns in MongoDB?

Data modeling patterns help design efficient data structures for specific use cases and query patterns.

  • Embedded documents: One-to-one, one-to-many
  • References: Many-to-many
  • Bucket pattern: Time-series data
  • Extended reference: Denormalized data
  • Subset pattern: Frequently accessed fields
mongodb
// MongoDB Data Modeling
// Data modeling patterns for MongoDB

// Embedded documents (one-to-one)
db.users.insertOne({
    _id: "user123",
    name: "Alice",
    address: {
        street: "123 Main St",
        city: "NYC",
        zip: "10001"
    }
});

// Array of embedded documents (one-to-many)
db.users.insertOne({
    _id: "user123",
    name: "Alice",
    orders: [
        { orderId: "ord1", amount: 100 },
        { orderId: "ord2", amount: 200 }
    ]
});

// Reference pattern (many-to-many)
db.orders.insertOne({
    _id: "ord1",
    customerId: "user123",
    amount: 100
});

// Bucket pattern (time-series)
db.sensorData.insertOne({
    sensorId: "sensor1",
    readings: [
        { timestamp: ISODate("2023-01-01T00:00:00Z"), value: 25 },
        { timestamp: ISODate("2023-01-01T00:01:00Z"), value: 26 }
    ]
});

// Extended reference pattern
db.orders.insertOne({
    _id: "ord1",
    customer: {
        id: "user123",
        name: "Alice",
        email: "alice@example.com"
    },
    amount: 100
});

// Subset pattern
db.products.insertOne({
    _id: "prod1",
    name: "Product 1",
    price: 99.99,
    // Detailed info stored separately
    detailsId: "detail1"
});
Advanced
29. What are query operators in MongoDB?

Query operators provide powerful filtering, comparison, and evaluation capabilities for queries.

  • Comparison: $eq, $gt, $lt, $in
  • Logical: $and, $or, $not
  • Element: $exists, $type
  • Evaluation: $regex, $expr
  • Array: $all, $elemMatch, $size
mongodb
// MongoDB Query Operators
// Comparison operators

// $eq - Equal to
db.users.find({ age: { $eq: 25 } });

// $gt - Greater than
db.users.find({ age: { $gt: 25 } });

// $gte - Greater than or equal
db.users.find({ age: { $gte: 25 } });

// $lt - Less than
db.users.find({ age: { $lt: 25 } });

// $lte - Less than or equal
db.users.find({ age: { $lte: 25 } });

// $ne - Not equal
db.users.find({ age: { $ne: 25 } });

// $in - In array
db.users.find({ city: { $in: ["NYC", "LA", "Chicago"] } });

// $nin - Not in array
db.users.find({ city: { $nin: ["NYC", "LA"] } });

// Logical operators
// $and
db.users.find({
    $and: [
        { age: { $gte: 18 } },
        { age: { $lte: 65 } }
    ]
});

// $or
db.users.find({
    $or: [
        { city: "NYC" },
        { status: "active" }
    ]
});

// $nor
db.users.find({
    $nor: [
        { status: "inactive" },
        { age: { $lt: 18 } }
    ]
});

// $not
db.users.find({
    age: { $not: { $lt: 18 } }
});

// Element operators
// $exists
db.users.find({ email: { $exists: true } });

// $type
db.users.find({ age: { $type: "int" } });

// Evaluation operators
// $regex
db.users.find({ name: { $regex: /^A/ } });

// $expr
db.users.find({
    $expr: {
        $gt: ["$age", "$minAge"]
    }
});

// $jsonSchema
db.users.find({
    $jsonSchema: {
        required: ["name", "age"]
    }
});

// Array operators
// $all
db.users.find({ hobbies: { $all: ["reading", "gaming"] } });

// $elemMatch
db.users.find({
    orders: {
        $elemMatch: {
            amount: { $gt: 100 },
            status: "completed"
        }
    }
});

// $size
db.users.find({ hobbies: { $size: 3 } });
Advanced
30. What are aggregation operators in MongoDB?

Aggregation operators provide powerful data transformation capabilities in the aggregation pipeline.

  • Grouping: $group, $sum, $avg
  • Projection: $project, $addFields
  • Array: $unwind, $push, $addToSet
  • Joins: $lookup
  • Conditional: $cond, $switch
mongodb
// MongoDB Aggregation Operators
// Grouping and accumulation

// $group - Group documents
db.orders.aggregate([
    {
        $group: {
            _id: "$customerId",
            totalAmount: { $sum: "$amount" },
            averageAmount: { $avg: "$amount" },
            minAmount: { $min: "$amount" },
            maxAmount: { $max: "$amount" },
            count: { $sum: 1 }
        }
    }
]);

// $project - Shape documents
db.users.aggregate([
    {
        $project: {
            name: 1,
            age: 1,
            ageInDays: { $multiply: ["$age", 365] },
            isAdult: { $gte: ["$age", 18] }
        }
    }
]);

// $unwind - Deconstruct array
db.orders.aggregate([
    { $unwind: "$items" },
    {
        $group: {
            _id: "$items.productId",
            totalSold: { $sum: "$items.quantity" }
        }
    }
]);

// $lookup - Join collections
db.orders.aggregate([
    {
        $lookup: {
            from: "customers",
            localField: "customerId",
            foreignField: "_id",
            as: "customer"
        }
    },
    { $unwind: "$customer" }
]);

// $addFields - Add computed fields
db.users.aggregate([
    {
        $addFields: {
            fullName: {
                $concat: ["$firstName", " ", "$lastName"]
            },
            ageCategory: {
                $switch: {
                    branches: [
                        { case: { $lt: ["$age", 18] }, then: "Minor" },
                        { case: { $lt: ["$age", 65] }, then: "Adult" }
                    ],
                    default: "Senior"
                }
            }
        }
    }
]);

// $sort - Sort documents
db.users.aggregate([
    { $sort: { age: -1, name: 1 } }
]);

// $limit - Limit results
db.users.aggregate([
    { $sort: { age: -1 } },
    { $limit: 10 }
]);

// $skip - Skip documents
db.users.aggregate([
    { $sort: { age: -1 } },
    { $skip: 10 },
    { $limit: 10 }
]);

// $sample - Random documents
db.users.aggregate([
    { $sample: { size: 5 } }
]);

// $facet - Multiple aggregations
db.orders.aggregate([
    {
        $facet: {
            totalRevenue: [
                { $group: { _id: null, total: { $sum: "$amount" } } }
            ],
            byStatus: [
                { $group: { _id: "$status", count: { $sum: 1 } } }
            ]
        }
    }
]);
Advanced
31. What are views in MongoDB?

Views are read-only virtual collections that present data from other collections. They are created using aggregation pipelines.

  • Create: db.createView("name", "source", [pipeline])
  • Read-only: Cannot write to views
  • Pipeline: $match, $project, $group
  • Materialized views: Using $merge
  • Drop: db.view.drop()
mongodb
// MongoDB Views
// Views are read-only virtual collections

// Create a view
db.createView("activeUsers", "users", [
    { $match: { status: "active" } }
]);

// View with computed fields
db.createView("userStats", "users", [
    {
        $project: {
            name: 1,
            age: 1,
            ageCategory: {
                $switch: {
                    branches: [
                        { case: { $lt: ["$age", 18] }, then: "Minor" },
                        { case: { $lt: ["$age", 65] }, then: "Adult" }
                    ],
                    default: "Senior"
                }
            }
        }
    }
]);

// View with aggregation
db.createView("orderSummary", "orders", [
    {
        $group: {
            _id: "$customerId",
            totalAmount: { $sum: "$amount" },
            orderCount: { $sum: 1 }
        }
    },
    {
        $lookup: {
            from: "customers",
            localField: "_id",
            foreignField: "_id",
            as: "customer"
        }
    },
    { $unwind: "$customer" }
]);

// Query a view
db.activeUsers.find({ age: { $gt: 18 } });

// On-demand materialized views
db.orders.aggregate([
    {
        $merge: {
            into: "materializedOrders",
            on: "_id",
            whenMatched: "replace",
            whenNotMatched: "insert"
        }
    }
]);

// Drop a view
db.activeUsers.drop();
Advanced
32. What is MapReduce in MongoDB?

MapReduce is a data processing framework that maps documents, reduces values, and outputs results. It's superseded by aggregation.

  • Map: Emit key-value pairs
  • Reduce: Aggregate values by key
  • Finalize: Post-processing
  • Output: Inline or collection
  • Alternatives: Use aggregation pipeline
mongodb
// MongoDB MapReduce
// MapReduce for data processing

// Basic MapReduce
db.orders.mapReduce(
    function() {
        emit(this.customerId, this.amount);
    },
    function(key, values) {
        return Array.sum(values);
    },
    {
        query: { status: "completed" },
        out: "customerTotal"
    }
);

// MapReduce with complex emit
db.orders.mapReduce(
    function() {
        emit(this.customerId, {
            total: this.amount,
            count: 1
        });
    },
    function(key, values) {
        var result = { total: 0, count: 0 };
        for (var i = 0; i < values.length; i++) {
            result.total += values[i].total;
            result.count += values[i].count;
        }
        return result;
    },
    {
        out: { inline: 1 }
    }
);

// MapReduce with finalize
db.orders.mapReduce(
    function() {
        emit(this.customerId, this.amount);
    },
    function(key, values) {
        return Array.sum(values);
    },
    {
        out: "customerStats",
        finalize: function(key, value) {
            return {
                customerId: key,
                totalAmount: value,
                formatted: "$" + value.toFixed(2)
            };
        }
    }
);

// MapReduce with scope
var scopeVars = {
    minAmount: 100
};

db.orders.mapReduce(
    function() {
        if (this.amount > minAmount) {
            emit(this.customerId, this.amount);
        }
    },
    function(key, values) {
        return Array.sum(values);
    },
    {
        out: "highValueCustomers",
        scope: scopeVars
    }
);
Advanced
34. What are geospatial queries in MongoDB?

Geospatial queries allow querying location-based data using 2dsphere and 2d indexes.

  • 2dsphere index: { location: "2dsphere" }
  • $near: { $near: { $geometry: {...}, $maxDistance: 1000 } }
  • $geoWithin: Within polygon
  • $geoIntersects: Intersects geometry
  • $geoNear: Aggregation stage
mongodb
// MongoDB Geospatial Queries
// Geospatial indexing and queries

// Create 2dsphere index
db.locations.createIndex({ location: "2dsphere" });

// Create 2d index
db.locations.createIndex({ location: "2d" });

// $near - Find nearby locations
db.locations.find({
    location: {
        $near: {
            $geometry: {
                type: "Point",
                coordinates: [-73.9667, 40.78]
            },
            $maxDistance: 1000
        }
    }
});

// $geoWithin - Within polygon
db.locations.find({
    location: {
        $geoWithin: {
            $geometry: {
                type: "Polygon",
                coordinates: [[
                    [-74.0, 40.7],
                    [-74.0, 40.8],
                    [-73.9, 40.8],
                    [-73.9, 40.7],
                    [-74.0, 40.7]
                ]]
            }
        }
    }
});

// $geoIntersects - Intersects geometry
db.locations.find({
    location: {
        $geoIntersects: {
            $geometry: {
                type: "LineString",
                coordinates: [
                    [-74.0, 40.7],
                    [-73.9, 40.8]
                ]
            }
        }
    }
});

// $geoWithin with center
db.locations.find({
    location: {
        $geoWithin: {
            $centerSphere: [
                [-73.9667, 40.78],
                0.01 // Radius in radians
            ]
        }
    }
});

// Geospatial aggregation
db.locations.aggregate([
    {
        $geoNear: {
            near: {
                type: "Point",
                coordinates: [-73.9667, 40.78]
            },
            distanceField: "distance",
            maxDistance: 1000,
            spherical: true
        }
    }
]);
Advanced
35. What is GridFS in MongoDB?

GridFS is a specification for storing and retrieving large files (larger than 16MB) in MongoDB.

  • Files: fs.files collection
  • Chunks: fs.chunks collection
  • Upload: bucket.uploadFromStream()
  • Download: bucket.openDownloadStream()
  • Metadata: Additional file information
mongodb
// MongoDB GridFS
// GridFS for storing large files

// Store a file
var fileId = new ObjectId();
var bucket = new GridFSBucket(db, { bucketName: "files" });

bucket.uploadFromStream("file.txt", fileStream, {
    _id: fileId,
    metadata: {
        owner: "user123",
        uploaded: new Date()
    }
});

// Download a file
var downloadStream = bucket.openDownloadStream(fileId);
downloadStream.pipe(fs.createWriteStream("downloaded.txt"));

// Find files
db.files.files.find({ "metadata.owner": "user123" });

// List files
bucket.find({ "metadata.owner": "user123" }).toArray();

// Delete a file
bucket.delete(fileId);

// Stream with progress
var uploadStream = bucket.openUploadStream("largeFile.txt", {
    chunkSizeBytes: 1024 * 1024,
    metadata: {
        type: "document",
        user: "user123"
    }
});

uploadStream.on("finish", function() {
    print("Upload completed");
});

uploadStream.on("error", function(error) {
    print("Upload error: " + error);
});

// Rename a file
bucket.rename(fileId, "newName.txt");
Advanced
36. What are capped collections in MongoDB?

Capped collections are fixed-size collections that maintain insertion order and automatically overwrite old documents.

  • Fixed size: { capped: true, size: 100000 }
  • Max documents: { max: 1000 }
  • Insertion order: Maintains order
  • Tailable cursors: cursor.tailable()
  • Use cases: Logging, caching
mongodb
// MongoDB Capped Collections
// Capped collections for fixed-size data

// Create capped collection
db.createCollection("logs", {
    capped: true,
    size: 100000,
    max: 1000
});

// Insert documents
db.logs.insertMany([
    { message: "Log entry 1", timestamp: new Date() },
    { message: "Log entry 2", timestamp: new Date() }
]);

// Tailable cursor
var cursor = db.logs.find().tailable();

cursor.forEach(function(doc) {
    print(doc.message);
});

// Using with change streams
var changeStream = db.logs.watch();

changeStream.on("change", function(change) {
    print("New log entry: " + change.fullDocument.message);
});

// Convert existing collection to capped
db.runCommand({
    convertToCapped: "myCollection",
    size: 100000
});

// Check if collection is capped
db.logs.isCapped();

// View collection stats
db.logs.stats();

// Capped collection limitations
// - Cannot be sharded
// - Cannot be updated if document grows
// - No indexes except _id
// - Order is insertion order
Advanced
37. What are TTL indexes in MongoDB?

TTL (Time-To-Live) indexes automatically delete documents after a specified time. They are useful for expiring data.

  • expireAfterSeconds: { expireAfterSeconds: 3600 }
  • Date field: { createdAt: 1 }
  • Partial filters: { partialFilterExpression: { status: "active" } }
  • Cleanup job: Runs periodically
  • Use cases: Session cleanup, data retention
mongodb
// MongoDB TTL Indexes
// TTL indexes for automatic document expiration

// Create TTL index
db.sessions.createIndex(
    { createdAt: 1 },
    { expireAfterSeconds: 3600 }
);

// TTL with specific expiry date
db.sessions.createIndex(
    { expireAt: 1 },
    { expireAfterSeconds: 0 }
);

// Documents with TTL
db.sessions.insertOne({
    userId: "user123",
    token: "abc123",
    createdAt: new Date(),
    expireAt: new Date(Date.now() + 3600000)
});

// TTL with partial filter
db.sessions.createIndex(
    { createdAt: 1 },
    {
        expireAfterSeconds: 3600,
        partialFilterExpression: { status: "active" }
    }
);

// TTL cleanup job
db.runCommand({
    compact: "sessions"
});

// Check TTL index
db.sessions.getIndexes();

// Drop TTL index
db.sessions.dropIndex("createdAt_1");

// TTL for different time periods
db.orders.createIndex(
    { createdAt: 1 },
    { expireAfterSeconds: 30 * 24 * 60 * 60 } // 30 days
);

db.tempData.createIndex(
    { createdAt: 1 },
    { expireAfterSeconds: 60 } // 1 minute
);
Advanced
38. What is the aggregation framework in MongoDB?

The aggregation framework provides powerful data processing capabilities through a pipeline of stages.

  • $lookup: Join collections with pipelines
  • $graphLookup: Recursive joins
  • $unionWith: Combine collections
  • $merge: Output to collection
  • $bucket: Group by ranges
mongodb
// MongoDB Aggregation Framework
// Advanced aggregation techniques

// $lookup with pipeline
db.orders.aggregate([
    {
        $lookup: {
            from: "customers",
            let: { customerId: "$customerId" },
            pipeline: [
                {
                    $match: {
                        $expr: {
                            $eq: ["$_id", "$$customerId"]
                        }
                    }
                },
                {
                    $project: {
                        _id: 0,
                        name: 1,
                        email: 1
                    }
                }
            ],
            as: "customer"
        }
    }
]);

// $graphLookup for recursive queries
db.employees.aggregate([
    {
        $graphLookup: {
            from: "employees",
            startWith: "$managerId",
            connectFromField: "managerId",
            connectToField: "_id",
            as: "managers",
            maxDepth: 5
        }
    }
]);

// $unionWith for combining collections
db.orders.aggregate([
    {
        $unionWith: {
            coll: "archivedOrders"
        }
    }
]);

// $merge for output
db.orders.aggregate([
    {
        $match: { status: "completed" }
    },
    {
        $merge: {
            into: "completedOrders",
            on: "_id",
            whenMatched: "replace",
            whenNotMatched: "insert"
        }
    }
]);

// $bucket for grouping
db.orders.aggregate([
    {
        $bucket: {
            groupBy: "$amount",
            boundaries: [0, 100, 500, 1000],
            default: "Other",
            output: {
                count: { $sum: 1 },
                total: { $sum: "$amount" }
            }
        }
    }
]);

// $bucketAuto for automatic buckets
db.orders.aggregate([
    {
        $bucketAuto: {
            groupBy: "$amount",
            buckets: 5,
            output: {
                count: { $sum: 1 },
                average: { $avg: "$amount" }
            }
        }
    }
]);
Advanced
39. How to optimize MongoDB performance?

Performance optimization involves proper indexing, query optimization, and efficient data modeling.

  • Indexes: Create appropriate indexes
  • Explain: Analyze query execution
  • Covered queries: Index-only queries
  • Projection: Return only needed fields
  • Bulk operations: Batch inserts/updates
mongodb
// MongoDB Performance Optimization
// Query optimization techniques

// Use proper indexes
db.users.createIndex({ email: 1 });
db.users.createIndex({ age: 1, status: 1 });

// Explain query
db.users.find({ email: "alice@example.com" }).explain("executionStats");

// Covered query
db.users.find(
    { email: "alice@example.com" },
    { _id: 0, email: 1, name: 1 }
);

// Query projection
db.users.find({ age: { $gt: 18 } }, { name: 1, age: 1 });

// Use $in with indexes
db.users.find({ city: { $in: ["NYC", "LA"] } });

// Avoid $where when possible
// Bad: db.users.find({ $where: "this.age > 18" })
// Good: db.users.find({ age: { $gt: 18 } })

// Use limit and skip for pagination
db.users.find().limit(20).skip(40);

// Use aggregation for complex queries
db.orders.aggregate([
    { $match: { status: "completed" } },
    { $group: { _id: "$customerId", total: { $sum: "$amount" } } },
    { $sort: { total: -1 } }
]);

// Bulk operations
var bulk = db.users.initializeUnorderedBulkOp();
bulk.insert({ name: "Alice" });
bulk.insert({ name: "Bob" });
bulk.execute();

// Use $hint to force index
db.users.find({ age: { $gt: 18 } }).hint({ age: 1 });

// Use $natural for collection scan
db.users.find().hint({ $natural: 1 });
Advanced
40. What are security features in MongoDB?

MongoDB provides authentication, authorization, encryption, and auditing for data security.

  • Authentication: SCRAM, X.509
  • Authorization: Role-based access control
  • Encryption: TLS/SSL, encryption at rest
  • Auditing: Activity logging
  • Field-level encryption: Client-side encryption
mongodb
// MongoDB Security
// Security features and best practices

// Enable authentication
use admin;
db.createUser({
    user: "admin",
    pwd: "password",
    roles: ["root"]
});

// Create database user
use myDatabase;
db.createUser({
    user: "appUser",
    pwd: "appPassword",
    roles: [
        { role: "readWrite", db: "myDatabase" }
    ]
});

// Role-based access control
db.createRole({
    role: "customRole",
    privileges: [
        {
            resource: { db: "myDatabase", collection: "users" },
            actions: ["find", "insert", "update"]
        }
    ],
    roles: []
});

// Enable TLS/SSL
// mongod --tlsMode requireTLS --tlsCertificateKeyFile /path/to/cert.pem

// Enable encryption at rest
// mongod --enableEncryption --encryptionKeyFile /path/to/key

// Audit logging
db.setLogLevel(1, "accessControl");

// Connection string with authentication
// mongodb://username:password@localhost:27017/database

// Client-side field level encryption
// Requires enterprise edition

// Database access control
db.users.find().readConcern("majority");

// Write concern
db.users.insertOne(
    { name: "Alice" },
    { writeConcern: { w: "majority", wtimeout: 5000 } }
);

// IP Whitelisting
// mongod --bind_ip 127.0.0.1,192.168.1.100

// Enable authorization
// mongod --auth
Coding Round
41. Find max value in MongoDB

Find maximum value using $max in aggregation or sorting with limit.

  • Aggregation: { $group: { _id: null, max: { $max: "$age" } } }
  • Sort: db.collection.find().sort({ age: -1 }).limit(1)
  • Array field: Use $unwind first
  • $facet: Multiple aggregates
mongodb
// MongoDB Backup and Restore
// Backup and restore methods

// mongodump - Backup
// mongodump --db myDatabase --out /backups/

// mongodump with gzip
// mongodump --db myDatabase --gzip --out /backups/

// mongodump specific collections
// mongodump --db myDatabase --collection users --out /backups/

// mongorestore - Restore
// mongorestore --db myDatabase /backups/myDatabase/

// mongorestore with gzip
// mongorestore --db myDatabase --gzip /backups/myDatabase/

// Backup with authentication
// mongodump --username admin --password password --authenticationDatabase admin

// Backup to archive
// mongodump --archive=/backups/dump.archive --db myDatabase

// Restore from archive
// mongorestore --archive=/backups/dump.archive

// Point-in-time recovery (with oplog)
// mongodump --oplog --out /backups/

// Restore with oplog
// mongorestore --oplogReplay /backups/

// Backup specific query
// mongodump --db myDatabase --collection users --query '{"status": "active"}'
Coding Round
42. Remove duplicates in MongoDB

Remove duplicates using aggregation to find duplicates and then delete them.

  • Find duplicates: $group with $push
  • Keep first: Use $first
  • Delete: db.collection.deleteMany()
  • $out: Create unique collection
mongodb
// MongoDB Monitoring
// Monitoring and performance tracking

// Server status
db.serverStatus();

// Database stats
db.stats();

// Collection stats
db.users.stats();

// Current operations
db.currentOp();

// Kill operation
db.killOp(opId);

// Query profiling
db.setProfilingLevel(2);

// Profiling level: 0-off, 1-slow, 2-all
db.getProfilingStatus();

// Slow query log
db.system.profile.find({ millis: { $gt: 100 } });

// Connection stats
db.serverStatus().connections;

// Memory stats
db.serverStatus().mem;

// Lock stats
db.serverStatus().locks;

// Replication lag
rs.printReplicationInfo();

// Oplog stats
db.getReplicationInfo();

// Index usage stats
db.users.aggregate([
    { $indexStats: {} }
]);

// Log rotation
db.adminCommand({ logRotate: 1 });

// Server status as JSON
printjson(db.serverStatus());
Coding Round
43. Merge arrays in MongoDB

Merge arrays using $concatArrays or $setUnion for unique values.

  • $concatArrays: { $concatArrays: ["$arr1", "$arr2"] }
  • $setUnion: { $setUnion: ["$arr1", "$arr2"] }
  • $reduce: Custom merge logic
  • $mergeObjects: Merge documents
mongodb
// Find max in array (MongoDB)
// Using aggregation
db.users.aggregate([
    { $group: { _id: null, maxAge: { $max: "$age" } } }
]);

// Using find with sort
db.users.find().sort({ age: -1 }).limit(1);

// Find max in array field
db.orders.aggregate([
    { $unwind: "$items" },
    { $group: { _id: null, maxPrice: { $max: "$items.price" } } }
]);

// Using $max in $project
db.users.aggregate([
    {
        $project: {
            name: 1,
            age: 1,
            maxAge: { $max: ["$age", "$parentAge"] }
        }
    }
]);

// Find document with max value
db.users.find({ age: { $eq: 25 } }).sort({ age: -1 }).limit(1);

// Using $facet for multiple aggregates
db.users.aggregate([
    {
        $facet: {
            maxAge: [
                { $group: { _id: null, max: { $max: "$age" } } }
            ],
            minAge: [
                { $group: { _id: null, min: { $min: "$age" } } }
            ]
        }
    }
]);
Coding Round
44. Convert string to number in MongoDB

Convert string to number using $toInt, $toDouble, or $toDecimal.

  • $toInt: { $toInt: "$age" }
  • $toDouble: { $toDouble: "$amount" }
  • $convert: With error handling
  • $cond: Handle invalid values
mongodb
// Remove duplicates (MongoDB)
// Using aggregation to find duplicates
db.users.aggregate([
    {
        $group: {
            _id: "$email",
            count: { $sum: 1 },
            ids: { $push: "$_id" }
        }
    },
    {
        $match: { count: { $gt: 1 } }
    }
]);

// Remove duplicates keeping first
var duplicates = db.users.aggregate([
    {
        $group: {
            _id: "$email",
            ids: { $push: "$_id" }
        }
    },
    {
        $match: { "ids.1": { $exists: true } }
    }
]);

duplicates.forEach(function(doc) {
    var keepId = doc.ids[0];
    var removeIds = doc.ids.slice(1);
    db.users.deleteMany({ _id: { $in: removeIds } });
});

// Remove duplicates using $out
db.users.aggregate([
    {
        $group: {
            _id: "$email",
            doc: { $first: "$$ROOT" }
        }
    },
    {
        $replaceRoot: { newRoot: "$doc" }
    },
    { $out: "uniqueUsers" }
]);

// Find duplicate emails
db.users.aggregate([
    {
        $group: {
            _id: "$email",
            count: { $sum: 1 }
        }
    },
    { $match: { count: { $gt: 1 } } }
]);
Coding Round
45. Loop through array in MongoDB

Loop through arrays using $map, $filter, $reduce, or $unwind.

  • $map: Transform each element
  • $filter: Select elements
  • $reduce: Aggregate elements
  • $unwind: Deconstruct array
mongodb
// Merge arrays (MongoDB)
// Using $concatArrays
db.users.aggregate([
    {
        $project: {
            name: 1,
            allHobbies: {
                $concatArrays: ["$hobbies", "$interests"]
            }
        }
    }
]);

// Merge arrays of objects
db.orders.aggregate([
    {
        $project: {
            allItems: {
                $concatArrays: ["$items", "$bonusItems"]
            }
        }
    }
]);

// Merge with unique values
db.users.aggregate([
    {
        $project: {
            name: 1,
            allHobbies: {
                $setUnion: ["$hobbies", "$interests"]
            }
        }
    }
]);

// Merge arrays from multiple documents
db.users.aggregate([
    {
        $group: {
            _id: null,
            allNames: { $push: "$name" }
        }
    },
    {
        $project: {
            allNames: {
                $reduce: {
                    input: "$allNames",
                    initialValue: [],
                    in: { $concatArrays: ["$$value", ["$$this"]] }
                }
            }
        }
    }
]);

// Merge with $mergeObjects
db.users.aggregate([
    {
        $group: {
            _id: "$userId",
            data: { $mergeObjects: "$$ROOT" }
        }
    }
]);
Coding Round
46. Delay function execution in MongoDB

Delay execution using sleep(), setTimeout, or scheduling tasks.

  • sleep(): sleep(1000)
  • setTimeout: setTimeout(fn, delay)
  • setInterval: setInterval(fn, interval)
  • Scheduled tasks: Store and poll
mongodb
// Convert string to number (MongoDB)
// Using $toInt
db.users.aggregate([
    {
        $project: {
            name: 1,
            ageInt: { $toInt: "$age" }
        }
    }
]);

// Convert string to decimal
db.orders.aggregate([
    {
        $project: {
            amountDecimal: { $toDecimal: "$amountString" }
        }
    }
]);

// Convert string to double
db.orders.aggregate([
    {
        $project: {
            amountDouble: { $toDouble: "$amountString" }
        }
    }
]);

// Safe conversion
db.users.aggregate([
    {
        $project: {
            age: {
                $convert: {
                    input: "$age",
                    to: "int",
                    onError: 0,
                    onNull: 0
                }
            }
        }
    }
]);

// Convert with $cond
db.users.aggregate([
    {
        $project: {
            age: {
                $cond: {
                    if: { $eq: [{ $type: "$age" }, "string"] },
                    then: { $toInt: "$age" },
                    else: "$age"
                }
            }
        }
    }
]);

// Convert multiple fields
db.orders.aggregate([
    {
        $project: {
            _id: 1,
            amount: { $toDecimal: "$amount" },
            quantity: { $toInt: "$quantity" }
        }
    }
]);
Coding Round
47. HTTP GET request in MongoDB

Make HTTP requests using MongoDB Atlas Data API or application-level code.

  • Atlas Data API: REST API to MongoDB
  • MongoDB Stitch: Serverless platform
  • Application code: Use HTTP client libraries
  • Third-party: Use with drivers
mongodb
// Loop through array (MongoDB)
// Using $map
db.users.aggregate([
    {
        $project: {
            name: 1,
            hobbiesUpperCase: {
                $map: {
                    input: "$hobbies",
                    as: "hobby",
                    in: { $toUpper: "$$hobby" }
                }
            }
        }
    }
]);

// Using $filter
db.users.aggregate([
    {
        $project: {
            name: 1,
            hobbies: {
                $filter: {
                    input: "$hobbies",
                    as: "hobby",
                    cond: { $ne: ["$$hobby", "gaming"] }
                }
            }
        }
    }
]);

// Using $reduce
db.users.aggregate([
    {
        $project: {
            name: 1,
            allHobbies: {
                $reduce: {
                    input: "$hobbies",
                    initialValue: "",
                    in: { $concat: ["$$value", "$$this", ", "] }
                }
            }
        }
    }
]);

// Using $forEach (with JavaScript)
db.users.find().forEach(function(user) {
    print("User: " + user.name);
    user.hobbies.forEach(function(hobby) {
        print("  - " + hobby);
    });
});

// Using $unwind for iteration
db.users.aggregate([
    { $unwind: "$hobbies" },
    { $group: { _id: "$_id", hobbies: { $push: "$hobbies" } } }
]);
Coding Round
48. Create a promise-like Deferred in MongoDB

Use JavaScript Promises with async/await in the mongo shell or application code.

  • Promise: new Promise((resolve, reject) => {})
  • async/await: async function() { await ... }
  • Callback: Traditional callback pattern
  • Chaining: then().catch()
mongodb
// Delay function execution (MongoDB)
// Using sleep in JavaScript
function delayedExecution(delayMs, fn) {
    sleep(delayMs);
    fn();
}

// Using setTimeout in mongosh
var timeoutId = setTimeout(function() {
    print("Executed after delay");
}, 2000);

// Clear timeout
clearTimeout(timeoutId);

// Using setInterval
var intervalId = setInterval(function() {
    print("Repeating execution");
}, 1000);

// Clear interval
clearInterval(intervalId);

// Using $currentDate with delay
db.scheduledTasks.insertOne({
    task: "processData",
    scheduledAt: new Date(Date.now() + 60000)
});

// Polling for scheduled tasks
function processScheduledTasks() {
    var tasks = db.scheduledTasks.find({
        scheduledAt: { $lt: new Date() }
    });
    tasks.forEach(function(task) {
        // Process task
        print("Processing task: " + task.task);
        db.scheduledTasks.deleteOne({ _id: task._id });
    });
}

// Periodic check
setInterval(processScheduledTasks, 5000);
Coding Round
49. Factorial in MongoDB

Calculate factorial using JavaScript functions or aggregation.

  • Recursive: function fact(n) { return n <= 1 ? 1 : n * fact(n-1) }
  • Iterative: Loop with multiplication
  • $reduce: Use $range and $reduce
  • Stored function: db.system.js.insert()
mongodb
// HTTP GET request (MongoDB)
// Using MongoDB Atlas Data API
// GET request to MongoDB Atlas
fetch('https://data.mongodb-api.com/app/data-xxx/endpoint/data/v1/action/find', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'api-key': 'your-api-key'
    },
    body: JSON.stringify({
        dataSource: 'cluster0',
        database: 'test',
        collection: 'users',
        filter: { status: 'active' }
    })
})
.then(response => response.json())
.then(data => console.log(data));

// Using MongoDB Stitch (Realm)
const client = new Stitch.StitchAppClient('your-app-id');
const db = client.getServiceClient(Stitch.RemoteMongoClient.factory, 'mongodb-atlas');

// Query data
db.db('test').collection('users').find({}).toArray()
    .then(users => console.log(users))
    .catch(error => console.error(error));

// Using HTTP GET with MongoDB ReST API
const axios = require('axios');

axios.get('http://localhost:27017/test/users', {
    auth: {
        username: 'admin',
        password: 'password'
    }
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
Coding Round
50. Fibonacci in MongoDB

Calculate Fibonacci numbers using recursion, iteration, or memoization.

  • Recursive: function fib(n) { return n <= 1 ? n : fib(n-1) + fib(n-2) }
  • Iterative: Loop with variables
  • Memoization: Cache results
  • $reduce: Fibonacci with aggregation
mongodb
// Create a promise-like Deferred (MongoDB)
// Using async/await in mongosh
function createDeferred(shouldResolve) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (shouldResolve) {
                resolve("Success!");
            } else {
                reject("Failed!");
            }
        }, 1000);
    });
}

// Usage
async function testDeferred() {
    try {
        var result = await createDeferred(true);
        print(result);
    } catch (error) {
        print("Caught: " + error);
    }
}

testDeferred();

// Using with MongoDB operations
async function findUser(userId) {
    return await db.users.findOne({ _id: userId });
}

// Execute async
findUser("user123")
    .then(user => printjson(user))
    .catch(error => print("Error: " + error));

// Multiple async operations
async function processUsers() {
    var users = await db.users.find({}).toArray();
    for (var user of users) {
        print("Processing: " + user.name);
    }
}

processUsers();
Coding Round
51. FizzBuzz in MongoDB

FizzBuzz using JavaScript loops or aggregation with $switch.

  • JavaScript: for loop with conditions
  • $switch: { $switch: { branches: [...] } }
  • $mod: { $mod: ["$num", 3] }
  • $function: Custom JavaScript in aggregation
mongodb
// Factorial (MongoDB)
// Using JavaScript in mongosh
function factorial(n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}
print(factorial(5)); // 120

// Iterative version
function factorialIterative(n) {
    var result = 1;
    for (var i = 2; i <= n; i++) {
        result *= i;
    }
    return result;
}

// Using aggregation
db.numbers.aggregate([
    {
        $project: {
            factorial: {
                $reduce: {
                    input: { $range: [1, { $add: ["$n", 1] }] },
                    initialValue: 1,
                    in: { $multiply: ["$$value", "$$this"] }
                }
            }
        }
    }
]);

// Using stored function
db.system.js.insertOne({
    _id: "factorial",
    value: function(n) {
        if (n <= 1) return 1;
        return n * factorial(n - 1);
    }
});

db.eval("factorial(5)"); // 120
Coding Round
52. Find missing number in MongoDB

Find missing number using formula, XOR, or set difference in aggregation.

  • Formula: total - sum
  • $setDifference: Expected vs actual numbers
  • $range: Generate expected numbers
  • JavaScript: Custom function
mongodb
// Fibonacci (MongoDB)
// Using JavaScript in mongosh
function fibonacci(n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}
print(fibonacci(8)); // 21

// Iterative version
function fibonacciIterative(n) {
    if (n <= 1) return n;
    var a = 0, b = 1;
    for (var i = 2; i <= n; i++) {
        var temp = a + b;
        a = b;
        b = temp;
    }
    return b;
}

// Memoized version
var fibMemo = {};
function fibonacciMemo(n) {
    if (n <= 1) return n;
    if (fibMemo[n]) return fibMemo[n];
    fibMemo[n] = fibonacciMemo(n - 1) + fibonacciMemo(n - 2);
    return fibMemo[n];
}

// Using aggregation (for small n)
db.numbers.aggregate([
    {
        $project: {
            fibonacci: {
                $reduce: {
                    input: { $range: [0, { $add: ["$n", 1] }] },
                    initialValue: [0, 1],
                    in: {
                        $concatArrays: [
                            "$$value",
                            [
                                {
                                    $add: [
                                        { $arrayElemAt: ["$$value", -1] },
                                        { $arrayElemAt: ["$$value", -2] }
                                    ]
                                }
                            ]
                        ]
                    }
                }
            }
        }
    }
]);
Coding Round
53. Find duplicates in MongoDB

Find duplicates using $group with $sum to count occurrences.

  • $group: { _id: "$field", count: { $sum: 1 } }
  • $match: { count: { $gt: 1 } }
  • $facet: Multiple duplicate detection
  • $push: Collect duplicate IDs
mongodb
// FizzBuzz (MongoDB)
// Using JavaScript in mongosh
function fizzBuzz(n) {
    for (var i = 1; i <= n; i++) {
        if (i % 15 === 0) {
            print("FizzBuzz");
        } else if (i % 3 === 0) {
            print("Fizz");
        } else if (i % 5 === 0) {
            print("Buzz");
        } else {
            print(i);
        }
    }
}
fizzBuzz(15);

// Using aggregation
db.numbers.insertMany(
    Array.from({length: 15}, (_, i) => ({ num: i + 1 }))
);

db.numbers.aggregate([
    {
        $project: {
            result: {
                $switch: {
                    branches: [
                        {
                            case: { $eq: [{ $mod: ["$num", 15] }, 0] },
                            then: "FizzBuzz"
                        },
                        {
                            case: { $eq: [{ $mod: ["$num", 3] }, 0] },
                            then: "Fizz"
                        },
                        {
                            case: { $eq: [{ $mod: ["$num", 5] }, 0] },
                            then: "Buzz"
                        }
                    ],
                    default: { $toString: "$num" }
                }
            }
        }
    }
]);

// Using $function (MongoDB 4.4+)
db.numbers.aggregate([
    {
        $project: {
            result: {
                $function: {
                    body: function(num) {
                        if (num % 15 === 0) return "FizzBuzz";
                        if (num % 3 === 0) return "Fizz";
                        if (num % 5 === 0) return "Buzz";
                        return String(num);
                    },
                    args: ["$num"],
                    lang: "js"
                }
            }
        }
    }
]);
Coding Round
54. Sum of array in MongoDB

Calculate sum using $sum in $group or $project.

  • $group: { $sum: "$field" }
  • $project: { total: { $sum: "$arrayField" } }
  • $reduce: Custom sum logic
  • $unwind: Sum nested arrays
mongodb
// Find missing number (MongoDB)
// Using JavaScript in mongosh
function findMissing(arr) {
    var n = arr.length + 1;
    var total = n * (n + 1) / 2;
    var sum = arr.reduce((a, b) => a + b, 0);
    return total - sum;
}
print(findMissing([1, 2, 4, 5, 6])); // 3

// Using aggregation
var numbers = [1, 2, 4, 5, 6];
db.numbers.insertMany(numbers.map(n => ({ num: n })));

db.numbers.aggregate([
    {
        $group: {
            _id: null,
            sum: { $sum: "$num" },
            count: { $sum: 1 }
        }
    },
    {
        $project: {
            missing: {
                $subtract: [
                    {
                        $multiply: [
                            { $divide: [{ $multiply: ["$count", { $add: ["$count", 1] }] }, 2] },
                            { $add: ["$count", 1] }
                        ]
                    },
                    "$sum"
                ]
            }
        }
    }
]);

// Using $setUnion for missing numbers
db.numbers.aggregate([
    {
        $group: {
            _id: null,
            numbers: { $push: "$num" }
        }
    },
    {
        $project: {
            numbers: 1,
            expected: {
                $range: [1, { $size: "$numbers" }]
            }
        }
    },
    {
        $project: {
            missing: {
                $setDifference: ["$expected", "$numbers"]
            }
        }
    }
]);
Coding Round
55. Average of array in MongoDB

Calculate average using $avg in $group or $project.

  • $group: { $avg: "$field" }
  • $project: { average: { $avg: "$arrayField" } }
  • Weighted average: { $divide: [{ $sum: "$arrayField" }, { $size: "$arrayField" }] }
  • Nested arrays: Use $unwind
mongodb
// Find duplicates (MongoDB)
// Using aggregation
db.users.aggregate([
    {
        $group: {
            _id: "$email",
            count: { $sum: 1 },
            docs: { $push: "$$ROOT" }
        }
    },
    {
        $match: { count: { $gt: 1 } }
    }
]);

// Find duplicate emails
db.users.aggregate([
    {
        $group: {
            _id: "$email",
            count: { $sum: 1 }
        }
    },
    {
        $match: { count: { $gt: 1 } }
    },
    {
        $project: {
            email: "$_id",
            count: 1,
            _id: 0
        }
    }
]);

// Find duplicates in array
db.users.aggregate([
    {
        $project: {
            name: 1,
            duplicateHobbies: {
                $reduce: {
                    input: "$hobbies",
                    initialValue: [],
                    in: {
                        $cond: [
                            { $in: ["$$this", "$$value"] },
                            { $concatArrays: ["$$value", ["$$this"]] },
                            "$$value"
                        ]
                    }
                }
            }
        }
    }
]);

// Using $facet for duplicate detection
db.users.aggregate([
    {
        $facet: {
            duplicates: [
                {
                    $group: {
                        _id: "$email",
                        count: { $sum: 1 }
                    }
                },
                { $match: { count: { $gt: 1 } } }
            ]
        }
    }
]);
Coding Round
56. Sort array ascending in MongoDB

Sort using $sort in aggregation or sort() in find.

  • $sort: { $sort: { field: 1 } }
  • Array sorting: $sortArray (MongoDB 5.0+)
  • Multi-field sort: { field1: 1, field2: 1 }
  • With limit: { $limit: 10 }
mongodb
// Sum of array (MongoDB)
// Using aggregation
db.orders.aggregate([
    {
        $group: {
            _id: null,
            total: { $sum: "$amount" }
        }
    }
]);

// Sum of array field
db.orders.aggregate([
    {
        $project: {
            orderId: 1,
            totalItems: { $sum: "$items.quantity" }
        }
    }
]);

// Sum with $reduce
db.orders.aggregate([
    {
        $project: {
            total: {
                $reduce: {
                    input: "$amounts",
                    initialValue: 0,
                    in: { $add: ["$$value", "$$this"] }
                }
            }
        }
    }
]);

// Sum of nested array
db.orders.aggregate([
    { $unwind: "$items" },
    {
        $group: {
            _id: "$_id",
            total: { $sum: { $multiply: ["$items.price", "$items.quantity"] } }
        }
    }
]);

// Sum with $project
db.orders.aggregate([
    {
        $project: {
            orderId: 1,
            total: {
                $sum: {
                    $map: {
                        input: "$items",
                        as: "item",
                        in: { $multiply: ["$$item.price", "$$item.quantity"] }
                    }
                }
            }
        }
    }
]);
Coding Round
57. Sort array descending in MongoDB

Sort descending using $sort with -1 or sort() with 'descend'.

  • $sort: { $sort: { field: -1 } }
  • Array sorting: $sortArray with -1
  • Multi-field: { field1: -1, field2: -1 }
  • With limit: { $limit: 10 }
mongodb
// Average of array (MongoDB)
// Using aggregation
db.orders.aggregate([
    {
        $group: {
            _id: null,
            average: { $avg: "$amount" }
        }
    }
]);

// Average of array field
db.users.aggregate([
    {
        $project: {
            name: 1,
            averageScore: { $avg: "$scores" }
        }
    }
]);

// Average with $reduce
db.orders.aggregate([
    {
        $project: {
            average: {
                $divide: [
                    {
                        $reduce: {
                            input: "$amounts",
                            initialValue: 0,
                            in: { $add: ["$$value", "$$this"] }
                        }
                    },
                    { $size: "$amounts" }
                ]
            }
        }
    }
]);

// Weighted average
db.orders.aggregate([
    { $unwind: "$items" },
    {
        $group: {
            _id: "$_id",
            weightedAverage: {
                $divide: [
                    { $sum: { $multiply: ["$items.price", "$items.quantity"] } },
                    { $sum: "$items.quantity" }
                ]
            }
        }
    }
]);

// Average of nested documents
db.orders.aggregate([
    { $unwind: "$items" },
    {
        $group: {
            _id: "$_id",
            averagePrice: { $avg: "$items.price" }
        }
    }
]);
Coding Round
58. Flatten nested array in MongoDB

Flatten nested arrays using $unwind multiple times or $reduce.

  • $unwind: { $unwind: "$array" }
  • Multiple unwind: Multiple $unwind stages
  • $reduce: { $concatArrays: [...] }
  • $project: With $map
mongodb
// Sort array ascending (MongoDB)
// Using $sort
db.users.aggregate([
    { $sort: { age: 1 } }
]);

// Sort with find
db.users.find().sort({ age: 1 });

// Sort nested field
db.orders.aggregate([
    { $sort: { "customer.name": 1 } }
]);

// Sort array field
db.users.aggregate([
    {
        $project: {
            name: 1,
            sortedHobbies: {
                $sortArray: {
                    input: "$hobbies",
                    sortBy: 1
                }
            }
        }
    }
]);

// Sort array of objects
db.users.aggregate([
    {
        $project: {
            name: 1,
            sortedOrders: {
                $sortArray: {
                    input: "$orders",
                    sortBy: { amount: 1 }
                }
            }
        }
    }
]);

// Multi-field sort
db.users.aggregate([
    { $sort: { age: 1, name: 1 } }
]);

// Sort with limit
db.users.find().sort({ age: 1 }).limit(10);
Coding Round
59. Chunk array in MongoDB

Split array into chunks using $reduce, $slice, or JavaScript.

  • $slice: { $slice: ["$array", start, size] }
  • $range: Generate indices
  • $reduce: Custom chunking
  • $function: JavaScript for chunking
mongodb
// Sort array descending (MongoDB)
// Using $sort
db.users.aggregate([
    { $sort: { age: -1 } }
]);

// Sort with find
db.users.find().sort({ age: -1 });

// Sort nested field descending
db.orders.aggregate([
    { $sort: { "customer.name": -1 } }
]);

// Sort array field descending
db.users.aggregate([
    {
        $project: {
            name: 1,
            sortedHobbies: {
                $sortArray: {
                    input: "$hobbies",
                    sortBy: -1
                }
            }
        }
    }
]);

// Sort array of objects descending
db.users.aggregate([
    {
        $project: {
            name: 1,
            sortedOrders: {
                $sortArray: {
                    input: "$orders",
                    sortBy: { amount: -1 }
                }
            }
        }
    }
]);

// Sort with compound descending
db.users.aggregate([
    { $sort: { age: -1, name: -1 } }
]);

// Sort with limit descending
db.users.find().sort({ age: -1 }).limit(10);
Coding Round
61. Quick sort in MongoDB

Quick sort using JavaScript functions or aggregation with $sortArray.

  • JavaScript: Recursive quick sort
  • $sortArray: { $sortArray: { input: "$array", sortBy: 1 } }
  • $sort: Sort documents
  • $function: Custom JavaScript sorting
mongodb
// Chunk array (MongoDB)
// Using JavaScript in mongosh
function chunkArray(arr, size) {
    var chunks = [];
    for (var i = 0; i < arr.length; i += size) {
        chunks.push(arr.slice(i, i + size));
    }
    return chunks;
}
printjson(chunkArray([1, 2, 3, 4, 5, 6], 2));

// Using aggregation
db.numbers.aggregate([
    {
        $project: {
            chunk: {
                $reduce: {
                    input: "$numbers",
                    initialValue: [],
                    in: {
                        $cond: [
                            { $eq: [{ $mod: [{ $size: "$$value" }, 2] }, 0] },
                            { $concatArrays: ["$$value", ["$$this"]] },
                            { $concatArrays: ["$$value", ["$$this"]] }
                        ]
                    }
                }
            }
        }
    }
]);

// Chunk using $slice
db.numbers.aggregate([
    {
        $project: {
            chunks: {
                $map: {
                    input: { $range: [0, { $size: "$numbers" }, 2] },
                    as: "start",
                    in: {
                        $slice: ["$numbers", "$$start", 2]
                    }
                }
            }
        }
    }
]);

// Chunk with custom size (using $function)
db.numbers.aggregate([
    {
        $project: {
            chunks: {
                $function: {
                    body: function(arr, size) {
                        var chunks = [];
                        for (var i = 0; i < arr.length; i += size) {
                            chunks.push(arr.slice(i, i + size));
                        }
                        return chunks;
                    },
                    args: ["$numbers", 2],
                    lang: "js"
                }
            }
        }
    }
]);
Coding Round
62. Merge sort in MongoDB

Merge sort using JavaScript functions or aggregation with $sortArray.

  • JavaScript: Recursive merge sort
  • $sortArray: { $sortArray: { input: "$array", sortBy: 1 } }
  • $sort: Sort documents
  • $function: Custom JavaScript sorting
mongodb
// Binary search (MongoDB)
// Using JavaScript in mongosh
function binarySearch(arr, target) {
    var left = 0;
    var right = arr.length - 1;
    while (left <= right) {
        var mid = Math.floor((left + right) / 2);
        if (arr[mid] === target) return mid;
        if (arr[mid] < target) left = mid + 1;
        else right = mid - 1;
    }
    return -1;
}
print(binarySearch([1, 2, 3, 4, 5, 6, 7], 5)); // 4

// Using aggregation
db.numbers.aggregate([
    {
        $project: {
            found: {
                $function: {
                    body: function(arr, target) {
                        var left = 0;
                        var right = arr.length - 1;
                        while (left <= right) {
                            var mid = Math.floor((left + right) / 2);
                            if (arr[mid] === target) return true;
                            if (arr[mid] < target) left = mid + 1;
                            else right = mid - 1;
                        }
                        return false;
                    },
                    args: ["$numbers", 5],
                    lang: "js"
                }
            }
        }
    }
]);

// Binary search in MongoDB index
db.users.find({ age: 25 }).explain(); // Uses index if available

// $search with Atlas Search
db.users.aggregate([
    {
        $search: {
            index: "default",
            text: {
                query: "Alice",
                path: "name"
            }
        }
    }
]);
Coding Round
63. Bubble sort in MongoDB

Bubble sort using JavaScript functions or $sortArray.

  • JavaScript: Nested loops
  • Optimized: Early termination
  • $sortArray: { $sortArray: { input: "$array", sortBy: 1 } }
  • $function: Custom JavaScript sorting
mongodb
// Quick sort (MongoDB)
// Using JavaScript in mongosh
function quickSort(arr) {
    if (arr.length <= 1) return arr;
    var pivot = arr[0];
    var left = [];
    var right = [];
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] < pivot) {
            left.push(arr[i]);
        } else {
            right.push(arr[i]);
        }
    }
    return [...quickSort(left), pivot, ...quickSort(right)];
}
printjson(quickSort([5, 3, 8, 4, 2, 7, 1, 6]));

// Using aggregation
db.numbers.aggregate([
    {
        $project: {
            sorted: {
                $function: {
                    body: function(arr) {
                        if (arr.length <= 1) return arr;
                        var pivot = arr[0];
                        var left = [];
                        var right = [];
                        for (var i = 1; i < arr.length; i++) {
                            if (arr[i] < pivot) {
                                left.push(arr[i]);
                            } else {
                                right.push(arr[i]);
                            }
                        }
                        return [...quickSort(left), pivot, ...quickSort(right)];
                    },
                    args: ["$numbers"],
                    lang: "js"
                }
            }
        }
    }
]);

// Using $sort for arrays (MongoDB 5.0+)
db.users.aggregate([
    {
        $project: {
            sortedHobbies: {
                $sortArray: {
                    input: "$hobbies",
                    sortBy: 1
                }
            }
        }
    }
]);
Coding Round
64. Intersection of arrays in MongoDB

Find intersection using $setIntersection or $filter.

  • $setIntersection: { $setIntersection: ["$arr1", "$arr2"] }
  • $filter: { $filter: { input: "$arr1", cond: { $in: ["$$item", "$arr2"] } } }
  • $reduce: Multiple arrays intersection
  • JavaScript: Custom intersection
mongodb
// Merge sort (MongoDB)
// Using JavaScript in mongosh
function mergeSort(arr) {
    if (arr.length <= 1) return arr;
    var mid = Math.floor(arr.length / 2);
    var left = arr.slice(0, mid);
    var right = arr.slice(mid);
    return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right) {
    var result = [];
    var i = 0, j = 0;
    while (i < left.length && j < right.length) {
        if (left[i] <= right[j]) {
            result.push(left[i++]);
        } else {
            result.push(right[j++]);
        }
    }
    return [...result, ...left.slice(i), ...right.slice(j)];
}
printjson(mergeSort([5, 3, 8, 4, 2, 7, 1, 6]));

// Using aggregation
db.numbers.aggregate([
    {
        $project: {
            sorted: {
                $function: {
                    body: function(arr) {
                        if (arr.length <= 1) return arr;
                        var mid = Math.floor(arr.length / 2);
                        var left = arr.slice(0, mid);
                        var right = arr.slice(mid);
                        return merge(mergeSort(left), mergeSort(right));
                    },
                    args: ["$numbers"],
                    lang: "js"
                }
            }
        }
    }
]);
Coding Round
65. Union of arrays in MongoDB

Find union using $setUnion or $concatArrays with $setUnion.

  • $setUnion: { $setUnion: ["$arr1", "$arr2"] }
  • $concatArrays: { $concatArrays: ["$arr1", "$arr2"] }
  • $reduce: Multiple arrays union
  • JavaScript: Custom union
mongodb
// Bubble sort (MongoDB)
// Using JavaScript in mongosh
function bubbleSort(arr) {
    var sorted = [...arr];
    for (var i = 0; i < sorted.length - 1; i++) {
        for (var j = 0; j < sorted.length - 1 - i; j++) {
            if (sorted[j] > sorted[j + 1]) {
                var temp = sorted[j];
                sorted[j] = sorted[j + 1];
                sorted[j + 1] = temp;
            }
        }
    }
    return sorted;
}
printjson(bubbleSort([5, 3, 8, 4, 2, 7, 1, 6]));

// Optimized bubble sort
function bubbleSortOptimized(arr) {
    var sorted = [...arr];
    for (var i = 0; i < sorted.length - 1; i++) {
        var swapped = false;
        for (var j = 0; j < sorted.length - 1 - i; j++) {
            if (sorted[j] > sorted[j + 1]) {
                var temp = sorted[j];
                sorted[j] = sorted[j + 1];
                sorted[j + 1] = temp;
                swapped = true;
            }
        }
        if (!swapped) break;
    }
    return sorted;
}

// Using aggregation with $function
db.numbers.aggregate([
    {
        $project: {
            sorted: {
                $function: {
                    body: function(arr) {
                        var sorted = [...arr];
                        for (var i = 0; i < sorted.length - 1; i++) {
                            for (var j = 0; j < sorted.length - 1 - i; j++) {
                                if (sorted[j] > sorted[j + 1]) {
                                    var temp = sorted[j];
                                    sorted[j] = sorted[j + 1];
                                    sorted[j + 1] = temp;
                                }
                            }
                        }
                        return sorted;
                    },
                    args: ["$numbers"],
                    lang: "js"
                }
            }
        }
    }
]);
Coding Round
66. Difference of arrays in MongoDB

Find difference using $setDifference or $filter.

  • $setDifference: { $setDifference: ["$arr1", "$arr2"] }
  • $filter: { $filter: { input: "$arr1", cond: { $not: { $in: ["$$item", "$arr2"] } } } }
  • Symmetric difference: Union of differences
  • JavaScript: Custom difference
mongodb
// Intersection of arrays (MongoDB)
// Using aggregation
db.users.aggregate([
    {
        $project: {
            name: 1,
            commonHobbies: {
                $setIntersection: ["$hobbies1", "$hobbies2"]
            }
        }
    }
]);

// Intersection with $filter
db.users.aggregate([
    {
        $project: {
            common: {
                $filter: {
                    input: "$arr1",
                    as: "item",
                    cond: { $in: ["$$item", "$arr2"] }
                }
            }
        }
    }
]);

// Intersection of multiple arrays
db.users.aggregate([
    {
        $project: {
            common: {
                $setIntersection: ["$arr1", "$arr2", "$arr3"]
            }
        }
    }
]);

// Using JavaScript in mongosh
function intersection(arr1, arr2) {
    return arr1.filter(x => arr2.includes(x));
}
printjson(intersection([1, 2, 3, 4], [3, 4, 5, 6]));

// Using $reduce for intersection
db.users.aggregate([
    {
        $project: {
            common: {
                $reduce: {
                    input: "$arr1",
                    initialValue: "$arr2",
                    in: {
                        $filter: {
                            input: "$$value",
                            as: "item",
                            cond: { $in: ["$$item", "$$this"] }
                        }
                    }
                }
            }
        }
    }
]);
Coding Round
67. Group by property in MongoDB

Group by property using $group with $sum and $push.

  • $group: { _id: "$field", count: { $sum: 1 } }
  • Multiple fields: { _id: { field1: "$f1", field2: "$f2" } }
  • $facet: Multiple group operations
  • Nested fields: { _id: "$nested.field" }
mongodb
// Union of arrays (MongoDB)
// Using $setUnion
db.users.aggregate([
    {
        $project: {
            name: 1,
            allHobbies: {
                $setUnion: ["$hobbies1", "$hobbies2"]
            }
        }
    }
]);

// Union with $concatArrays and $setUnion
db.users.aggregate([
    {
        $project: {
            all: {
                $setUnion: [
                    { $concatArrays: ["$arr1", "$arr2"] }
                ]
            }
        }
    }
]);

// Union of multiple arrays
db.users.aggregate([
    {
        $project: {
            all: {
                $setUnion: ["$arr1", "$arr2", "$arr3"]
            }
        }
    }
]);

// Using JavaScript in mongosh
function union(arr1, arr2) {
    return [...new Set([...arr1, ...arr2])];
}
printjson(union([1, 2, 3], [3, 4, 5]));

// Union with $reduce
db.users.aggregate([
    {
        $project: {
            all: {
                $reduce: {
                    input: ["$arr1", "$arr2", "$arr3"],
                    initialValue: [],
                    in: { $setUnion: ["$$value", "$$this"] }
                }
            }
        }
    }
]);
Coding Round
68. Deep clone object in MongoDB

Deep clone using JavaScript or JSON.parse(JSON.stringify()).

  • JSON method: JSON.parse(JSON.stringify(obj))
  • Recursive: Custom clone function
  • Spread operator: { ...obj } (shallow)
  • Object.assign: Object.assign(, obj) (shallow)
mongodb
// Difference of arrays (MongoDB)
// Using $setDifference
db.users.aggregate([
    {
        $project: {
            name: 1,
            diff: {
                $setDifference: ["$arr1", "$arr2"]
            }
        }
    }
]);

// Difference with $filter
db.users.aggregate([
    {
        $project: {
            diff: {
                $filter: {
                    input: "$arr1",
                    as: "item",
                    cond: { $not: { $in: ["$$item", "$arr2"] } }
                }
            }
        }
    }
]);

// Symmetric difference
db.users.aggregate([
    {
        $project: {
            symmetricDiff: {
                $setUnion: [
                    { $setDifference: ["$arr1", "$arr2"] },
                    { $setDifference: ["$arr2", "$arr1"] }
                ]
            }
        }
    }
]);

// Using JavaScript in mongosh
function difference(arr1, arr2) {
    return arr1.filter(x => !arr2.includes(x));
}
printjson(difference([1, 2, 3, 4], [3, 4, 5, 6]));

// Symmetric difference
function symmetricDifference(arr1, arr2) {
    var diff1 = arr1.filter(x => !arr2.includes(x));
    var diff2 = arr2.filter(x => !arr1.includes(x));
    return [...diff1, ...diff2];
}
printjson(symmetricDifference([1, 2, 3], [3, 4, 5]));
Coding Round
69. Immutable update in MongoDB

Immutable updates using $set to modify fields without overwriting entire documents.

  • $set: { $set: { field: value } }
  • Nested fields: { $set: { "nested.field": value } }
  • $addToSet: Add to array if not exists
  • $unset: Remove field
mongodb
// Group by property (MongoDB)
// Using $group
db.users.aggregate([
    {
        $group: {
            _id: "$city",
            count: { $sum: 1 },
            users: { $push: "$$ROOT" }
        }
    }
]);

// Group with multiple fields
db.orders.aggregate([
    {
        $group: {
            _id: {
                customerId: "$customerId",
                status: "$status"
            },
            total: { $sum: "$amount" },
            count: { $sum: 1 }
        }
    }
]);

// Group with $facet
db.orders.aggregate([
    {
        $facet: {
            byCustomer: [
                {
                    $group: {
                        _id: "$customerId",
                        total: { $sum: "$amount" }
                    }
                }
            ],
            byStatus: [
                {
                    $group: {
                        _id: "$status",
                        count: { $sum: 1 }
                    }
                }
            ]
        }
    }
]);

// Group by date
db.orders.aggregate([
    {
        $group: {
            _id: {
                year: { $year: "$createdAt" },
                month: { $month: "$createdAt" }
            },
            total: { $sum: "$amount" }
        }
    }
]);

// Group by nested field
db.orders.aggregate([
    {
        $group: {
            _id: "$customer.city",
            total: { $sum: "$amount" }
        }
    }
]);
Coding Round
70. Pipe function in MongoDB

Pipe using aggregation stages chained together or $facet for multiple pipelines.

  • Aggregation: Chained stages
  • $facet: Multiple parallel pipelines
  • $unionWith: Combine pipelines
  • $lookup: Join with pipeline
mongodb
// Deep clone object (MongoDB)
// Using JavaScript in mongosh
function deepClone(obj) {
    if (obj === null || typeof obj !== 'object') return obj;
    if (Array.isArray(obj)) {
        return obj.map(item => deepClone(item));
    }
    var cloned = {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            cloned[key] = deepClone(obj[key]);
        }
    }
    return cloned;
}

// Usage
var original = {
    name: "Alice",
    address: {
        city: "NYC",
        zip: "10001"
    }
};
var cloned = deepClone(original);
cloned.name = "Bob";
print(original.name); // Alice
print(cloned.name); // Bob

// Using JSON methods (shallow clone for complex)
var shallowClone = JSON.parse(JSON.stringify(original));

// Using spread operator
var spreadClone = { ...original };

// Using Object.assign
var assignClone = Object.assign({}, original);

// Deep clone with MongoDB document
var doc = db.users.findOne({ _id: ObjectId() });
var clonedDoc = JSON.parse(JSON.stringify(doc));
Coding Round
71. Compose function in MongoDB

Function composition using multiple stages or JavaScript compose function.

  • Stages: db.collection.aggregate([stage1, stage2])
  • $function: { $function: { body: compose(...) } }
  • JavaScript: const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x)
  • Chaining: Method chaining
mongodb
// Immutable update (MongoDB)
// Using $set for updates
db.users.updateOne(
    { _id: "user123" },
    { $set: { "address.city": "LA" } }
);

// Immutable update with aggregation
db.users.aggregate([
    {
        $project: {
            name: 1,
            address: {
                $mergeObjects: [
                    "$address",
                    { city: "LA" }
                ]
            }
        }
    }
]);

// Updating nested field immutably
db.users.updateOne(
    { _id: "user123" },
    {
        $set: {
            "address.city": "LA",
            "address.zip": "90001"
        }
    }
);

// Updating array immutably
db.users.updateOne(
    { _id: "user123" },
    { $addToSet: { hobbies: "reading" } }
);

// Removing field immutably
db.users.updateOne(
    { _id: "user123" },
    { $unset: { temporaryField: "" } }
);

// Multiple immutable updates
db.users.updateOne(
    { _id: "user123" },
    {
        $set: { "address.city": "LA" },
        $inc: { age: 1 },
        $push: { hobbies: "gaming" }
    }
);
Coding Round
72. Memoization in MongoDB

Memoization using cache objects or MongoDB collection for persistent caching.

  • Cache object: const cache =
  • MongoDB cache: Store in collection
  • TTL cache: With expiration
  • Function: function memoize(fn) { ... }
mongodb
// Pipe function (MongoDB)
// Using aggregation pipeline
db.users.aggregate([
    {
        $match: { age: { $gte: 18 } }
    },
    {
        $project: {
            name: 1,
            ageInDays: { $multiply: ["$age", 365] }
        }
    },
    {
        $sort: { age: -1 }
    },
    {
        $limit: 10
    }
]);

// Pipe using $facet
db.orders.aggregate([
    {
        $facet: {
            totalRevenue: [
                { $group: { _id: null, total: { $sum: "$amount" } } }
            ],
            topCustomers: [
                { $group: { _id: "$customerId", total: { $sum: "$amount" } } },
                { $sort: { total: -1 } },
                { $limit: 10 }
            ]
        }
    }
]);

// Pipe using $unionWith
db.orders.aggregate([
    {
        $match: { status: "pending" }
    },
    {
        $unionWith: {
            coll: "archivedOrders",
            pipeline: [
                { $match: { status: "pending" } }
            ]
        }
    }
]);

// Pipe using $lookup
db.orders.aggregate([
    {
        $lookup: {
            from: "customers",
            localField: "customerId",
            foreignField: "_id",
            as: "customer"
        }
    },
    { $unwind: "$customer" },
    {
        $project: {
            orderId: 1,
            amount: 1,
            customerName: "$customer.name"
        }
    }
]);
Coding Round
73. Once function in MongoDB

Ensure a function is called only once using closure with a flag.

  • Closure: let called = false
  • MongoDB flag: Store in collection
  • Lock: Prevent concurrent execution
  • Module pattern: Encapsulate state
mongodb
// Compose function (MongoDB)
// Using aggregation with $function
db.numbers.aggregate([
    {
        $project: {
            result: {
                $function: {
                    body: function(num) {
                        function double(x) { return x * 2; }
                        function addTen(x) { return x + 10; }
                        function square(x) { return x * x; }
                        var compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);
                        var process = compose(square, addTen, double);
                        return process(num);
                    },
                    args: ["$num"],
                    lang: "js"
                }
            }
        }
    }
]);

// Compose using multiple stages
db.numbers.aggregate([
    {
        $project: {
            value: { $multiply: ["$value", 2] } // double
        }
    },
    {
        $project: {
            value: { $add: ["$value", 10] } // addTen
        }
    },
    {
        $project: {
            value: { $pow: ["$value", 2] } // square
        }
    }
]);

// Function composition in JavaScript
function compose(...fns) {
    return function(x) {
        return fns.reduceRight((v, f) => f(v), x);
    };
}

var double = x => x * 2;
var addTen = x => x + 10;
var square = x => x * x;
var process = compose(square, addTen, double);
print(process(5)); // 400
Coding Round
74. Debounce with leading edge in MongoDB

Debounce with leading edge using timers and flag to track execution.

  • Timer: setTimeout
  • Leading edge: Execute immediately, then wait
  • MongoDB: Store last execution time
  • Application: Use in UI events
mongodb
// Memoization (MongoDB)
// Using JavaScript in mongosh
function memoize(fn) {
    var cache = {};
    return function(arg) {
        var key = JSON.stringify(arg);
        if (cache[key] !== undefined) {
            return cache[key];
        }
        var result = fn(arg);
        cache[key] = result;
        return result;
    };
}

// Fibonacci with memoization
var fibMemo = memoize(function(n) {
    if (n <= 1) return n;
    return fibMemo(n - 1) + fibMemo(n - 2);
});

print(fibMemo(10));

// Using MongoDB for caching
function memoizeWithDB(fn, key) {
    var cached = db.cache.findOne({ key: key });
    if (cached) {
        return cached.value;
    }
    var result = fn();
    db.cache.insertOne({ key: key, value: result });
    return result;
}

// Expiring cache
function memoizeWithTTL(fn, key, ttlSeconds) {
    var cached = db.cache.findOne({ key: key });
    if (cached && Date.now() - cached.timestamp < ttlSeconds * 1000) {
        return cached.value;
    }
    var result = fn();
    db.cache.updateOne(
        { key: key },
        { $set: { value: result, timestamp: Date.now() } },
        { upsert: true }
    );
    return result;
}
Coding Round
75. Throttle with leading edge in MongoDB

Throttle with leading edge ensuring at most one execution per time period.

  • Time check: Compare with last execution time
  • Leading edge: Execute immediately if enough time passed
  • MongoDB: Store last execution time
  • Application: Rate limiting
mongodb
// Once function (MongoDB)
// Using JavaScript in mongosh
function once(fn) {
    var called = false;
    var result = null;
    return function() {
        if (!called) {
            called = true;
            result = fn();
        }
        return result;
    };
}

// Usage
var initialize = once(function() {
    print("Initialized");
    return { id: 1, name: "App" };
});

printjson(initialize()); // Prints "Initialized"
printjson(initialize()); // Returns cached result

// Using MongoDB for initialization tracking
function onceWithDB(fn, key) {
    var initialized = db.initFlags.findOne({ key: key });
    if (initialized) {
        return initialized.value;
    }
    var result = fn();
    db.initFlags.insertOne({ key: key, value: result });
    return result;
}

// Once with lock for concurrent access
function onceWithLock(fn) {
    var lock = false;
    var result = null;
    return function() {
        if (!lock) {
            lock = true;
            result = fn();
        }
        return result;
    };
}

// Module pattern for once initialization
var App = {
    _initialized: false,
    _data: null,
    initialize: function(data) {
        if (!this._initialized) {
            this._data = data;
            this._initialized = true;
        }
        return this._data;
    }
};
Coding Round
76. Deep equal in MongoDB

Deep equality using recursive comparison or JSON.stringify for simple cases.

  • Recursive: Compare each property
  • JSON: JSON.stringify(obj1) === JSON.stringify(obj2)
  • $eq: In aggregation for fields
  • Application: Use in validation
mongodb
// Debounce with leading edge (MongoDB)
// Using JavaScript in mongosh
function debounceLeading(delayMs, fn) {
    var lastCall = 0;
    var timer = null;
    return function() {
        var now = Date.now();
        if (now - lastCall < delayMs) {
            if (timer) clearTimeout(timer);
            timer = setTimeout(function() {
                lastCall = Date.now();
                fn();
            }, delayMs);
        } else {
            lastCall = now;
            fn();
        }
    };
}

// Usage
var debounced = debounceLeading(1000, function() {
    print("Executed");
});

debounced(); // Executes immediately
debounced(); // Scheduled for later

// Using MongoDB with debounce
function debounceMongo(delayMs, fn, key) {
    var lastCall = 0;
    var timer = null;
    return function() {
        var now = Date.now();
        if (now - lastCall < delayMs) {
            if (timer) clearTimeout(timer);
            timer = setTimeout(function() {
                lastCall = Date.now();
                fn();
            }, delayMs);
        } else {
            lastCall = now;
            fn();
        }
    };
}

// Debounce with database
function debounceWithDB(delayMs, fn, key) {
    var timer = null;
    return function() {
        if (timer) clearTimeout(timer);
        timer = setTimeout(function() {
            db.debounced.updateOne(
                { key: key },
                { $set: { executed: new Date() } },
                { upsert: true }
            );
            fn();
        }, delayMs);
    };
}
Coding Round
77. Observable pattern in MongoDB

Observable pattern using change streams for real-time notifications.

  • Change streams: db.collection.watch()
  • Subscribers: on("change", callback)
  • Custom observable: Implement with JavaScript
  • Events: insert, update, delete
mongodb
// Throttle with leading edge (MongoDB)
// Using JavaScript in mongosh
function throttleLeading(delayMs, fn) {
    var lastCall = 0;
    return function() {
        var now = Date.now();
        if (now - lastCall >= delayMs) {
            lastCall = now;
            fn();
        }
    };
}

// Usage
var throttled = throttleLeading(1000, function() {
    print("Executed");
});

throttled(); // Executes
throttled(); // Ignored (within 1 second)

// Throttle with trailing edge
function throttleTrailing(delayMs, fn) {
    var lastCall = 0;
    var timer = null;
    return function() {
        var now = Date.now();
        if (now - lastCall >= delayMs) {
            lastCall = now;
            fn();
        } else if (!timer) {
            timer = setTimeout(function() {
                timer = null;
                lastCall = Date.now();
                fn();
            }, delayMs - (now - lastCall));
        }
    };
}

// Throttle with MongoDB
function throttleMongo(delayMs, fn, key) {
    var lastCall = 0;
    return function() {
        var now = Date.now();
        if (now - lastCall >= delayMs) {
            lastCall = now;
            db.throttled.updateOne(
                { key: key },
                { $set: { lastExecuted: new Date() } },
                { upsert: true }
            );
            fn();
        }
    };
}
Coding Round
78. Singleton pattern in MongoDB

Singleton pattern using module pattern or class with static instance.

  • Module pattern: IIFE with private instance
  • Class: Static getInstance method
  • Global: global.singleton = new Singleton()
  • MongoDB: Use for connection management
mongodb
// Deep equal (MongoDB)
// Using JavaScript in mongosh
function deepEqual(obj1, obj2) {
    if (obj1 === obj2) return true;
    if (obj1 === null || obj2 === null) return false;
    if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return false;
    if (Array.isArray(obj1) !== Array.isArray(obj2)) return false;
    
    if (Array.isArray(obj1)) {
        if (obj1.length !== obj2.length) return false;
        for (var i = 0; i < obj1.length; i++) {
            if (!deepEqual(obj1[i], obj2[i])) return false;
        }
        return true;
    }
    
    var keys1 = Object.keys(obj1);
    var keys2 = Object.keys(obj2);
    if (keys1.length !== keys2.length) return false;
    
    for (var key of keys1) {
        if (!obj2.hasOwnProperty(key)) return false;
        if (!deepEqual(obj1[key], obj2[key])) return false;
    }
    return true;
}

// Usage
var obj1 = { name: "Alice", address: { city: "NYC" } };
var obj2 = { name: "Alice", address: { city: "NYC" } };
print(deepEqual(obj1, obj2)); // true

// Using MongoDB comparison
db.users.findOne({ name: "Alice" })
    .then(user1 => {
        db.users.findOne({ name: "Alice" })
            .then(user2 => {
                var isEqual = JSON.stringify(user1) === JSON.stringify(user2);
                print(isEqual);
            });
    });

// Deep equal with $eq
db.users.aggregate([
    {
        $project: {
            isEqual: {
                $eq: ["$address", "$savedAddress"]
            }
        }
    }
]);
Coding Round
79. Factory pattern in MongoDB

Factory pattern using functions that create and return objects based on type.

  • Factory function: function createUser(type, data) { ... }
  • Switch/case: Create different object types
  • Validation: Validate input before creation
  • MongoDB: Create and insert documents
mongodb
// Observable pattern (MongoDB)
// Using Change Streams
var changeStream = db.users.watch();

changeStream.on("change", function(change) {
    print("Change detected!");
    printjson(change);
});

// Observable with custom events
class Observable {
    constructor() {
        this.subscribers = [];
    }
    
    subscribe(callback) {
        this.subscribers.push(callback);
        return () => {
            this.subscribers = this.subscribers.filter(cb => cb !== callback);
        };
    }
    
    notify(data) {
        this.subscribers.forEach(callback => callback(data));
    }
}

// Usage
var observable = new Observable();
var unsubscribe = observable.subscribe(function(data) {
    print("Received: " + JSON.stringify(data));
});

observable.notify({ message: "Hello" });
unsubscribe();

// Observable with MongoDB
function createObservable(collection) {
    var changeStream = collection.watch();
    var subscribers = [];
    
    changeStream.on("change", function(change) {
        subscribers.forEach(callback => callback(change));
    });
    
    return {
        subscribe: function(callback) {
            subscribers.push(callback);
            return () => {
                subscribers = subscribers.filter(cb => cb !== callback);
            };
        },
        close: function() {
            changeStream.close();
        }
    };
}

// Usage with collection
var userObservable = createObservable(db.users);
userObservable.subscribe(change => print("User change: " + change.operationType));
Coding Round
80. Strategy pattern in MongoDB

Strategy pattern using functions or objects with different algorithms.

  • Strategy functions: Different implementation
  • Context: Uses strategy
  • Dynamic switching: Change at runtime
  • MongoDB: Different processing strategies
mongodb
// Singleton pattern (MongoDB)
// Using module pattern
var Singleton = (function() {
    var instance = null;
    
    function createInstance() {
        var data = {};
        return {
            set: function(key, value) {
                data[key] = value;
            },
            get: function(key) {
                return data[key];
            },
            getAll: function() {
                return data;
            }
        };
    }
    
    return {
        getInstance: function() {
            if (!instance) {
                instance = createInstance();
            }
            return instance;
        }
    };
})();

// Usage
var singleton1 = Singleton.getInstance();
var singleton2 = Singleton.getInstance();
singleton1.set("name", "Alice");
print(singleton2.get("name")); // Alice

// Singleton with MongoDB
var MongoSingleton = (function() {
    var connection = null;
    
    function createConnection() {
        return db.getMongo();
    }
    
    return {
        getConnection: function() {
            if (!connection) {
                connection = createConnection();
            }
            return connection;
        }
    };
})();

// Singleton for database
var DBManager = (function() {
    var instance = null;
    
    function createManager() {
        return {
            getCollection: function(name) {
                return db.getCollection(name);
            },
            getDatabase: function() {
                return db;
            }
        };
    }
    
    return {
        getInstance: function() {
            if (!instance) {
                instance = createManager();
            }
            return instance;
        }
    };
})();

// Usage
var manager1 = DBManager.getInstance();
var manager2 = DBManager.getInstance();
print(manager1 === manager2); // true
Coding Round
81. Observer pattern in MongoDB

Observer pattern using change streams or custom event system.

  • Change streams: Real-time notifications
  • Custom events: Event emitter pattern
  • Multiple collections: Watch multiple collections
  • Filters: Match specific operations
mongodb
// Factory pattern (MongoDB)
// Using JavaScript functions
function createUser(type, name) {
    switch(type) {
        case 'admin':
            return {
                type: 'admin',
                name: name,
                permissions: ['read', 'write', 'delete']
            };
        case 'guest':
            return {
                type: 'guest',
                name: name,
                permissions: ['read']
            };
        default:
            return {
                type: 'regular',
                name: name,
                permissions: ['read', 'write']
            };
    }
}

// Usage
var admin = createUser('admin', 'Alice');
printjson(admin);

// Factory with MongoDB insertion
function createUserInDB(type, name) {
    var user = createUser(type, name);
    db.users.insertOne(user);
    return user;
}

// Factory with validation
function createValidatedUser(data) {
    var required = ['name', 'email'];
    for (var field of required) {
        if (!data[field]) {
            throw new Error('Missing required field: ' + field);
        }
    }
    
    var user = {
        _id: new ObjectId(),
        name: data.name,
        email: data.email,
        age: data.age || null,
        status: data.status || 'active',
        createdAt: new Date()
    };
    
    return user;
}

// Factory pattern with inheritance
function UserFactory() {
    this.create = function(type, data) {
        switch(type) {
            case 'customer':
                return new Customer(data);
            case 'employee':
                return new Employee(data);
            default:
                throw new Error('Invalid user type');
        }
    };
}

function Customer(data) {
    this.type = 'customer';
    this.name = data.name;
    this.accountNumber = data.accountNumber;
}

function Employee(data) {
    this.type = 'employee';
    this.name = data.name;
    this.employeeId = data.employeeId;
}
Coding Round
82. Decorator pattern in MongoDB

Decorator pattern using wrapper functions that enhance objects.

  • Wrapper functions: Enhance functionality
  • Chaining: Multiple decorators
  • MongoDB: Enhance documents with metadata
  • Validation: Validate decorated objects
mongodb
// Strategy pattern (MongoDB)
// Using JavaScript functions
function createPaymentStrategy(type) {
    switch(type) {
        case 'credit':
            return function(amount) {
                print("Paid $" + amount + " with Credit Card");
            };
        case 'paypal':
            return function(amount) {
                print("Paid $" + amount + " with PayPal");
            };
        case 'crypto':
            return function(amount) {
                print("Paid $" + amount + " with Crypto");
            };
        default:
            return function(amount) {
                print("Paid $" + amount + " with Unknown method");
            };
    }
}

// Usage
var creditStrategy = createPaymentStrategy('credit');
var paypalStrategy = createPaymentStrategy('paypal');
creditStrategy(100);
paypalStrategy(50);

// Strategy with context
var PaymentContext = function(strategy) {
    this.strategy = strategy;
    this.execute = function(amount) {
        this.strategy(amount);
    };
};

// Usage
var context = new PaymentContext(creditStrategy);
context.execute(100);

// Strategy pattern with MongoDB
var ProcessStrategy = {
    'insert': function(collection, data) {
        return collection.insertOne(data);
    },
    'update': function(collection, filter, data) {
        return collection.updateOne(filter, { $set: data });
    },
    'delete': function(collection, filter) {
        return collection.deleteOne(filter);
    }
};

function processData(collection, data, strategy) {
    return ProcessStrategy[strategy](collection, data);
}

// Usage
processData(db.users, { name: "Alice" }, 'insert');
processData(db.users, { name: "Alice" }, 'delete');

// Strategy with aggregation
db.orders.aggregate([
    {
        $group: {
            _id: {
                $switch: {
                    branches: [
                        { case: { $lt: ["$amount", 100] }, then: "small" },
                        { case: { $lt: ["$amount", 500] }, then: "medium" }
                    ],
                    default: "large"
                }
            },
            count: { $sum: 1 }
        }
    }
]);
Coding Round
83. Command pattern in MongoDB

Command pattern using objects with execute and undo methods.

  • Command object: Execute and undo methods
  • History: Stack of executed commands
  • MongoDB: Database operations as commands
  • Undo/Redo: Transaction support
mongodb
// Observer pattern (MongoDB)
// Using Change Streams
var observer = {
    onInsert: function(change) {
        print("New document inserted: " + change.fullDocument._id);
    },
    onUpdate: function(change) {
        print("Document updated: " + change.documentKey._id);
    },
    onDelete: function(change) {
        print("Document deleted: " + change.documentKey._id);
    }
};

var changeStream = db.users.watch();
changeStream.on("change", function(change) {
    switch(change.operationType) {
        case 'insert':
            observer.onInsert(change);
            break;
        case 'update':
            observer.onUpdate(change);
            break;
        case 'delete':
            observer.onDelete(change);
            break;
    }
});

// Custom observable
var Observable = function() {
    this.observers = [];
    
    this.subscribe = function(observer) {
        this.observers.push(observer);
        return () => {
            this.observers = this.observers.filter(o => o !== observer);
        };
    };
    
    this.notify = function(data) {
        this.observers.forEach(observer => observer(data));
    };
};

// Observer pattern with multiple collections
var dbObserver = {
    collections: {},
    
    observe: function(collectionName) {
        var changeStream = db[collectionName].watch();
        this.collections[collectionName] = changeStream;
        
        changeStream.on("change", function(change) {
            print("Change on " + collectionName + ": " + change.operationType);
        });
    },
    
    stopObserving: function(collectionName) {
        if (this.collections[collectionName]) {
            this.collections[collectionName].close();
            delete this.collections[collectionName];
        }
    }
};

// Usage
dbObserver.observe('users');
dbObserver.observe('orders');

// Observer with pipeline filtering
var filteredStream = db.users.watch([
    {
        $match: {
            operationType: 'insert'
        }
    }
]);

filteredStream.on("change", function(change) {
    print("New user inserted: " + change.fullDocument.name);
});
Coding Round
84. Memento pattern in MongoDB

Memento pattern using snapshots of document state for recovery.

  • Snapshot: JSON.parse(JSON.stringify(doc))
  • Restore: db.collection.updateOne({ _id: id }, { $set: snapshot })
  • History: Store multiple snapshots
  • Version control: Document versioning
mongodb
// Decorator pattern (MongoDB)
// Using JavaScript functions
function coffee() {
    this.cost = 5.0;
    this.description = "Coffee";
}

function milkDecorator(coffee) {
    var decorated = Object.create(coffee);
    decorated.cost = coffee.cost + 2.0;
    decorated.description = coffee.description + ", Milk";
    return decorated;
}

function sugarDecorator(coffee) {
    var decorated = Object.create(coffee);
    decorated.cost = coffee.cost + 1.0;
    decorated.description = coffee.description + ", Sugar";
    return decorated;
}

// Usage
var myCoffee = new coffee();
myCoffee = milkDecorator(myCoffee);
myCoffee = sugarDecorator(myCoffee);
print(myCoffee.description); // Coffee, Milk, Sugar
print(myCoffee.cost); // 8.0

// Decorator with MongoDB documents
function documentDecorator(doc) {
    return {
        ...doc,
        createdAt: new Date(),
        updatedAt: new Date(),
        toJSON: function() {
            return {
                ...doc,
                _id: doc._id.toString()
            };
        }
    };
}

function timestampDecorator(doc) {
    return {
        ...doc,
        createdAt: new Date(),
        updatedAt: new Date()
    };
}

function logDecorator(doc, collection) {
    return {
        ...doc,
        log: function() {
            print("Document inserted into " + collection);
        }
    };
}

// Usage
var user = { name: "Alice", age: 25 };
user = timestampDecorator(user);
user = logDecorator(user, "users");
db.users.insertOne(user);
user.log();

// Decorator with validation
function validateDecorator(schema, doc) {
    for (var field in schema) {
        if (schema[field].required && !doc[field]) {
            throw new Error("Missing required field: " + field);
        }
        if (schema[field].type && typeof doc[field] !== schema[field].type) {
            throw new Error("Invalid type for field: " + field);
        }
    }
    return doc;
}
Coding Round
85. Mediator pattern in MongoDB

Mediator pattern for centralized communication between components.

  • Mediator: Centralized coordinator
  • Colleagues: Communicate through mediator
  • MongoDB: Database mediator for collections
  • Decoupling: Reduce direct dependencies
mongodb
// Command pattern (MongoDB)
// Using JavaScript functions
function AddCommand(receiver, value) {
    this.receiver = receiver;
    this.value = value;
    
    this.execute = function() {
        this.receiver.push(this.value);
        print("Added: " + this.value);
    };
    
    this.undo = function() {
        var index = this.receiver.indexOf(this.value);
        if (index > -1) {
            this.receiver.splice(index, 1);
            print("Undo: Removed " + this.value);
        }
    };
}

// Usage
var receiver = [1, 2, 3];
var cmd = new AddCommand(receiver, 4);
cmd.execute();
printjson(receiver); // [1, 2, 3, 4]
cmd.undo();
printjson(receiver); // [1, 2, 3]

// Command pattern with MongoDB
function MongoCommand(collection, operation, data) {
    this.collection = collection;
    this.operation = operation;
    this.data = data;
    this.result = null;
    
    this.execute = function() {
        switch(this.operation) {
            case 'insert':
                this.result = this.collection.insertOne(this.data);
                break;
            case 'update':
                this.result = this.collection.updateOne(
                    { _id: this.data._id },
                    { $set: this.data }
                );
                break;
            case 'delete':
                this.result = this.collection.deleteOne({ _id: this.data._id });
                break;
        }
        return this.result;
    };
    
    this.undo = function() {
        switch(this.operation) {
            case 'insert':
                this.collection.deleteOne({ _id: this.result.insertedId });
                break;
            case 'update':
                // Revert to previous state (not implemented in this example)
                break;
            case 'delete':
                this.collection.insertOne(this.data);
                break;
        }
    };
}

// Command manager
var CommandManager = {
    history: [],
    execute: function(command) {
        command.execute();
        this.history.push(command);
    },
    undo: function() {
        var command = this.history.pop();
        if (command) {
            command.undo();
        }
    }
};

// Usage
var insertCmd = new MongoCommand(db.users, 'insert', { name: "Alice" });
CommandManager.execute(insertCmd);
CommandManager.undo();
Coding Round
86. Chain of Responsibility in MongoDB

Chain of Responsibility for sequential processing of requests.

  • Handlers: Process or forward
  • Chain: Linked list of handlers
  • MongoDB: Validation chain, middleware
  • Flexibility: Add/remove handlers
mongodb
// Memento pattern (MongoDB)
// Using JavaScript functions
function Memento(state) {
    this.state = state;
}

function Originator() {
    this.state = null;
    
    this.saveState = function() {
        return new Memento(JSON.parse(JSON.stringify(this.state)));
    };
    
    this.restoreState = function(memento) {
        this.state = memento.state;
        print("State restored: " + JSON.stringify(this.state));
    };
}

function Caretaker() {
    this.mementos = [];
    
    this.addMemento = function(memento) {
        this.mementos.push(memento);
    };
    
    this.getMemento = function(index) {
        return this.mementos[index];
    };
}

// Usage
var originator = new Originator();
var caretaker = new Caretaker();

originator.state = { name: "State 1" };
caretaker.addMemento(originator.saveState());

originator.state = { name: "State 2" };
caretaker.addMemento(originator.saveState());

originator.state = { name: "State 3" };

originator.restoreState(caretaker.getMemento(0));
print(originator.state.name); // State 1

// Memento with MongoDB
function MongoMemento(collection, documentId) {
    this.documentId = documentId;
    this.snapshot = null;
    
    this.save = function() {
        var doc = collection.findOne({ _id: documentId });
        this.snapshot = JSON.parse(JSON.stringify(doc));
        return this;
    };
    
    this.restore = function() {
        collection.updateOne(
            { _id: this.documentId },
            { $set: this.snapshot }
        );
        return this;
    };
}

// Memento manager
var SnapshotManager = {
    snapshots: {},
    
    save: function(collection, id) {
        var key = collection._name + ':' + id;
        var doc = collection.findOne({ _id: id });
        this.snapshots[key] = JSON.parse(JSON.stringify(doc));
        print("Snapshot saved: " + key);
    },
    
    restore: function(collection, id) {
        var key = collection._name + ':' + id;
        var snapshot = this.snapshots[key];
        if (snapshot) {
            collection.updateOne(
                { _id: id },
                { $set: snapshot }
            );
            print("Snapshot restored: " + key);
        }
    }
};

// Usage
db.users.insertOne({ _id: "user123", name: "Alice", age: 25 });
SnapshotManager.save(db.users, "user123");
db.users.updateOne({ _id: "user123" }, { $set: { age: 26 } });
SnapshotManager.restore(db.users, "user123");
Coding Round
87. State pattern in MongoDB

State pattern for managing object state transitions.

  • State object: Behavior depends on state
  • Transitions: Allowed state changes
  • MongoDB: Document status field
  • Validation: Validate state transitions
mongodb
// Mediator pattern (MongoDB)
// Using JavaScript functions
function Mediator() {
    this.colleagues = [];
    
    this.register = function(colleague) {
        this.colleagues.push(colleague);
        colleague.mediator = this;
    };
    
    this.send = function(message, sender) {
        this.colleagues.forEach(function(colleague) {
            if (colleague !== sender) {
                colleague.receive(message);
            }
        });
    };
}

function Colleague(name) {
    this.name = name;
    this.mediator = null;
    
    this.send = function(message) {
        if (this.mediator) {
            this.mediator.send(message, this);
        }
    };
    
    this.receive = function(message) {
        print(this.name + " received: " + message);
    };
}

// Usage
var mediator = new Mediator();
var alice = new Colleague("Alice");
var bob = new Colleague("Bob");
mediator.register(alice);
mediator.register(bob);
alice.send("Hello Bob!");

// Mediator with MongoDB
var DatabaseMediator = {
    collections: {},
    
    register: function(name, collection) {
        this.collections[name] = collection;
    },
    
    query: function(collectionName, query) {
        if (this.collections[collectionName]) {
            return this.collections[collectionName].find(query).toArray();
        }
        return [];
    },
    
    insert: function(collectionName, data) {
        if (this.collections[collectionName]) {
            return this.collections[collectionName].insertOne(data);
        }
        return null;
    },
    
    update: function(collectionName, filter, data) {
        if (this.collections[collectionName]) {
            return this.collections[collectionName].updateOne(filter, { $set: data });
        }
        return null;
    },
    
    delete: function(collectionName, filter) {
        if (this.collections[collectionName]) {
            return this.collections[collectionName].deleteOne(filter);
        }
        return null;
    }
};

// Usage
DatabaseMediator.register('users', db.users);
DatabaseMediator.register('orders', db.orders);

var users = DatabaseMediator.query('users', {});
printjson(users);

DatabaseMediator.insert('users', { name: "Alice", age: 25 });
DatabaseMediator.update('users', { name: "Alice" }, { age: 26 });
DatabaseMediator.delete('users', { name: "Alice" });
Coding Round
88. Proxy pattern in MongoDB

Proxy pattern for controlling access to objects.

  • Proxy: Controls access
  • Real object: Actual implementation
  • Lazy loading: Load on demand
  • MongoDB: Query proxy, cache proxy
mongodb
// Chain of Responsibility (MongoDB)
// Using JavaScript functions
function Handler() {
    this.nextHandler = null;
    
    this.setNext = function(handler) {
        this.nextHandler = handler;
        return handler;
    };
    
    this.handle = function(request) {
        if (this.nextHandler) {
            return this.nextHandler.handle(request);
        }
        return null;
    };
}

function AuthHandler() {
    this.handle = function(request) {
        if (request.token) {
            print("Authentication passed");
            if (this.nextHandler) {
                return this.nextHandler.handle(request);
            }
        } else {
            print("Authentication failed");
            return null;
        }
    };
}
AuthHandler.prototype = Object.create(Handler.prototype);

function LoggerHandler() {
    this.handle = function(request) {
        print("Logging request: " + request.url);
        if (this.nextHandler) {
            return this.nextHandler.handle(request);
        }
        return null;
    };
}
LoggerHandler.prototype = Object.create(Handler.prototype);

function PermissionHandler() {
    this.handle = function(request) {
        if (request.permissions && request.permissions.includes('read')) {
            print("Permission granted");
            if (this.nextHandler) {
                return this.nextHandler.handle(request);
            }
        } else {
            print("Permission denied");
            return null;
        }
    };
}
PermissionHandler.prototype = Object.create(Handler.prototype);

// Usage
var auth = new AuthHandler();
var logger = new LoggerHandler();
var permission = new PermissionHandler();

auth.setNext(logger).setNext(permission);
auth.handle({
    token: "valid",
    url: "/api/data",
    permissions: ['read']
});

// Chain with MongoDB
var ValidationChain = {
    steps: [],
    
    addStep: function(step) {
        this.steps.push(step);
        return this;
    },
    
    validate: function(document) {
        var result = document;
        for (var step of this.steps) {
            result = step(result);
            if (!result) {
                print("Validation failed at " + step.name);
                return null;
            }
        }
        return result;
    }
};

// Usage
function requiredFields(fields) {
    return function(doc) {
        for (var field of fields) {
            if (!doc[field]) {
                print("Missing field: " + field);
                return null;
            }
        }
        return doc;
    };
}

function validateTypes(schema) {
    return function(doc) {
        for (var field in schema) {
            if (doc[field] && typeof doc[field] !== schema[field]) {
                print("Invalid type for " + field);
                return null;
            }
        }
        return doc;
    };
}

var validator = ValidationChain
    .addStep(requiredFields(['name', 'email']))
    .addStep(validateTypes({ name: 'string', age: 'number' }));

var validDoc = validator.validate({ name: "Alice", email: "alice@example.com", age: 25 });
var invalidDoc = validator.validate({ name: "Bob", age: "25" });
Coding Round
89. Flyweight pattern in MongoDB

Flyweight pattern for sharing objects to save memory.

  • Flyweight: Shared object
  • Factory: Manages flyweights
  • MongoDB: Shared schemas, cached documents
  • Performance: Memory optimization
mongodb
// State pattern (MongoDB)
// Using JavaScript functions
function State() {
    this.handle = function() {};
}

function ReadyState() {
    this.handle = function() {
        print("Ready: Waiting for input");
    };
}
ReadyState.prototype = Object.create(State.prototype);

function ProcessingState() {
    this.handle = function() {
        print("Processing: Working on task");
    };
}
ProcessingState.prototype = Object.create(State.prototype);

function CompletedState() {
    this.handle = function() {
        print("Completed: Task finished");
    };
}
CompletedState.prototype = Object.create(State.prototype);

function Context() {
    this.state = new ReadyState();
    
    this.setState = function(state) {
        this.state = state;
    };
    
    this.request = function() {
        this.state.handle();
    };
}

// Usage
var context = new Context();
context.request(); // Ready: Waiting for input
context.setState(new ProcessingState());
context.request(); // Processing: Working on task
context.setState(new CompletedState());
context.request(); // Completed: Task finished

// State pattern with MongoDB
function OrderState() {
    this.status = 'pending';
    this.transitions = {};
    
    this.canTransition = function(newState) {
        return this.transitions[this.status] && 
               this.transitions[this.status].includes(newState);
    };
    
    this.transition = function(newState) {
        if (this.canTransition(newState)) {
            this.status = newState;
            print("Order status changed to: " + newState);
            return true;
        }
        print("Invalid transition from " + this.status + " to " + newState);
        return false;
    };
}

// Order state with allowed transitions
var orderState = new OrderState();
orderState.transitions = {
    'pending': ['processing', 'cancelled'],
    'processing': ['shipped', 'cancelled'],
    'shipped': ['delivered', 'returned'],
    'delivered': ['returned']
};

// Usage
orderState.transition('processing');
orderState.transition('shipped');
orderState.transition('delivered');

// State in MongoDB document
db.orders.insertOne({
    _id: "order123",
    status: "pending",
    transitions: [
        { from: "pending", to: "processing", timestamp: new Date() }
    ]
});

db.orders.updateOne(
    { _id: "order123", status: "pending" },
    {
        $set: { status: "processing" },
        $push: { transitions: { from: "pending", to: "processing", timestamp: new Date() } }
    }
);
Coding Round
90. Bridge pattern in MongoDB

Bridge pattern for separating abstraction from implementation.

  • Abstraction: High-level interface
  • Implementation: Low-level operations
  • MongoDB: Repository pattern, data access
  • Flexibility: Change implementation
mongodb
// Proxy pattern (MongoDB)
// Using JavaScript functions
function RealSubject() {
    this.request = function() {
        print("RealSubject: Handling request");
    };
}

function Proxy() {
    this.realSubject = null;
    
    this.request = function() {
        if (this.checkAccess()) {
            if (!this.realSubject) {
                this.realSubject = new RealSubject();
            }
            this.realSubject.request();
            this.logAccess();
        }
    };
    
    this.checkAccess = function() {
        print("Proxy: Checking access");
        return true;
    };
    
    this.logAccess = function() {
        print("Proxy: Logging access");
    };
}

// Usage
var proxy = new Proxy();
proxy.request();

// Proxy with MongoDB
function MongoProxy(collection) {
    this.collection = collection;
    this.cache = {};
    
    this.find = function(filter) {
        var key = JSON.stringify(filter);
        if (this.cache[key]) {
            print("Cache hit for: " + key);
            return this.cache[key];
        }
        print("Cache miss for: " + key);
        var result = this.collection.find(filter).toArray();
        this.cache[key] = result;
        return result;
    };
    
    this.insert = function(data) {
        print("Inserting: " + JSON.stringify(data));
        var result = this.collection.insertOne(data);
        // Invalidate cache
        this.cache = {};
        return result;
    };
    
    this.clearCache = function() {
        this.cache = {};
        print("Cache cleared");
    };
}

// Usage
var proxy = new MongoProxy(db.users);
proxy.find({ age: { $gt: 18 } });
proxy.find({ age: { $gt: 18 } }); // Cache hit
proxy.insert({ name: "Alice", age: 25 });
proxy.find({ age: { $gt: 18 } }); // Cache miss (cache cleared)

// Virtual proxy (lazy loading)
function VirtualProxy(collection, id) {
    this.collection = collection;
    this.id = id;
    this.realObject = null;
    
    this.get = function() {
        if (!this.realObject) {
            print("Loading document from database");
            this.realObject = this.collection.findOne({ _id: this.id });
        }
        return this.realObject;
    };
}

// Usage
var proxy2 = new VirtualProxy(db.users, "user123");
var user = proxy2.get(); // Loads from DB
var user2 = proxy2.get(); // Returns cached object
Coding Round
91. Adapter pattern in MongoDB

Adapter pattern for converting interfaces.

  • Adapter: Converts interface
  • Adaptee: Existing interface
  • MongoDB: SQL to MongoDB adapter
  • Compatibility: Make incompatible classes work
mongodb
// Flyweight pattern (MongoDB)
// Using JavaScript functions
function Flyweight(sharedState) {
    this.sharedState = sharedState;
    this.operation = function(uniqueState) {
        print("Shared: " + this.sharedState + ", Unique: " + uniqueState);
    };
}

function FlyweightFactory() {
    this.flyweights = {};
    
    this.getFlyweight = function(sharedState) {
        var key = JSON.stringify(sharedState);
        if (!this.flyweights[key]) {
            this.flyweights[key] = new Flyweight(sharedState);
            print("Creating new flyweight for: " + sharedState);
        }
        return this.flyweights[key];
    };
}

// Usage
var factory = new FlyweightFactory();
var fw1 = factory.getFlyweight("state1");
var fw2 = factory.getFlyweight("state1");
var fw3 = factory.getFlyweight("state2");
fw1.operation("unique1");
fw2.operation("unique2");
fw3.operation("unique3");

// Flyweight with MongoDB
function DocumentFlyweight(schema) {
    this.schema = schema;
    this.cache = {};
    
    this.getDocument = function(data) {
        var key = JSON.stringify(data);
        if (this.cache[key]) {
            return this.cache[key];
        }
        var doc = {};
        for (var field in this.schema) {
            doc[field] = data[field] || this.schema[field].default || null;
        }
        this.cache[key] = doc;
        return doc;
    };
}

// Usage
var userSchema = {
    name: { type: 'string', default: 'Unknown' },
    age: { type: 'number', default: 0 },
    city: { type: 'string', default: 'Unknown' }
};

var flyweight = new DocumentFlyweight(userSchema);
var doc1 = flyweight.getDocument({ name: "Alice", age: 25 });
var doc2 = flyweight.getDocument({ name: "Alice", age: 25 });
print(doc1 === doc2); // true (same object)

// Flyweight for repeated values
function ArrayFlyweight() {
    this.cache = {};
    
    this.getArray = function(values) {
        var key = values.join(',');
        if (!this.cache[key]) {
            this.cache[key] = values;
        }
        return this.cache[key];
    };
}

// Usage
var arrayFactory = new ArrayFlyweight();
var arr1 = arrayFactory.getArray([1, 2, 3]);
var arr2 = arrayFactory.getArray([1, 2, 3]);
print(arr1 === arr2); // true
Coding Round
92. Facade pattern in MongoDB

Facade pattern for simplifying complex subsystems.

  • Facade: Simplified interface
  • Subsystem: Complex components
  • MongoDB: Database facade, query builder
  • Simplicity: Hide complexity
mongodb
// Bridge pattern (MongoDB)
// Using JavaScript functions
function Implementation() {
    this.operation = function() {};
}

function ConcreteImplementationA() {
    this.operation = function() {
        print("ConcreteImplementationA: Operation");
    };
}
ConcreteImplementationA.prototype = Object.create(Implementation.prototype);

function ConcreteImplementationB() {
    this.operation = function() {
        print("ConcreteImplementationB: Operation");
    };
}
ConcreteImplementationB.prototype = Object.create(Implementation.prototype);

function Abstraction(impl) {
    this.impl = impl;
    this.operation = function() {
        print("Abstraction: Additional logic");
        this.impl.operation();
    };
}

// Usage
var implA = new ConcreteImplementationA();
var implB = new ConcreteImplementationB();
var abstraction1 = new Abstraction(implA);
var abstraction2 = new Abstraction(implB);
abstraction1.operation();
abstraction2.operation();

// Bridge with MongoDB
function MongoImplementation() {
    this.collection = null;
    this.query = function() {};
    this.insert = function() {};
    this.update = function() {};
    this.delete = function() {};
}

function UserImplementation() {
    this.collection = db.users;
    this.query = function(filter) {
        return this.collection.find(filter).toArray();
    };
    this.insert = function(data) {
        return this.collection.insertOne(data);
    };
    this.update = function(filter, data) {
        return this.collection.updateOne(filter, { $set: data });
    };
    this.delete = function(filter) {
        return this.collection.deleteOne(filter);
    };
}
UserImplementation.prototype = Object.create(MongoImplementation.prototype);

function OrderImplementation() {
    this.collection = db.orders;
    this.query = function(filter) {
        return this.collection.find(filter).toArray();
    };
    this.insert = function(data) {
        return this.collection.insertOne(data);
    };
    this.update = function(filter, data) {
        return this.collection.updateOne(filter, { $set: data });
    };
    this.delete = function(filter) {
        return this.collection.deleteOne(filter);
    };
}
OrderImplementation.prototype = Object.create(MongoImplementation.prototype);

function Repository(impl) {
    this.impl = impl;
    
    this.findAll = function() {
        return this.impl.query({});
    };
    
    this.findById = function(id) {
        return this.impl.query({ _id: id });
    };
    
    this.save = function(data) {
        return this.impl.insert(data);
    };
    
    this.update = function(id, data) {
        return this.impl.update({ _id: id }, data);
    };
    
    this.delete = function(id) {
        return this.impl.delete({ _id: id });
    };
}

// Usage
var userRepo = new Repository(new UserImplementation());
var orderRepo = new Repository(new OrderImplementation());

userRepo.save({ name: "Alice", age: 25 });
orderRepo.save({ customerId: "user123", amount: 100 });
Coding Round
93. Composite pattern in MongoDB

Composite pattern for tree structures.

  • Component: Interface for all
  • Leaf: Individual object
  • Composite: Container
  • MongoDB: Schema composition, nested documents
mongodb
// Adapter pattern (MongoDB)
// Using JavaScript functions
function Target() {
    this.request = function() {
        print("Target: Request");
    };
}

function Adaptee() {
    this.specificRequest = function() {
        print("Adaptee: Specific Request");
    };
}

function Adapter(adaptee) {
    this.adaptee = adaptee;
    this.request = function() {
        this.adaptee.specificRequest();
    };
}

// Usage
var adaptee = new Adaptee();
var adapter = new Adapter(adaptee);
adapter.request();

// Adapter with MongoDB
function MongoDBAdapter() {
    this.db = db;
    
    // Adapter methods
    this.find = function(collection, query) {
        return this.db[collection].find(query).toArray();
    };
    
    this.insert = function(collection, data) {
        return this.db[collection].insertOne(data);
    };
    
    this.update = function(collection, filter, data) {
        return this.db[collection].updateOne(filter, { $set: data });
    };
    
    this.delete = function(collection, filter) {
        return this.db[collection].deleteOne(filter);
    };
}

// SQL to MongoDB adapter
function SQLtoMongoAdapter() {
    this.select = function(collection, fields) {
        var projection = {};
        fields.forEach(function(field) {
            projection[field] = 1;
        });
        return { collection: collection, projection: projection };
    };
    
    this.where = function(query, conditions) {
        query.filter = conditions;
        return query;
    };
    
    this.orderBy = function(query, field, direction) {
        query.sort = {};
        query.sort[field] = direction === 'desc' ? -1 : 1;
        return query;
    };
    
    this.limit = function(query, count) {
        query.limit = count;
        return query;
    };
    
    this.execute = function(query) {
        var cursor = db[query.collection].find(query.filter || {});
        if (query.projection) {
            cursor = cursor.project(query.projection);
        }
        if (query.sort) {
            cursor = cursor.sort(query.sort);
        }
        if (query.limit) {
            cursor = cursor.limit(query.limit);
        }
        return cursor.toArray();
    };
}

// Usage
var adapter = new SQLtoMongoAdapter();
var query = adapter.select('users', ['name', 'age']);
query = adapter.where(query, { age: { $gt: 18 } });
query = adapter.orderBy(query, 'name', 'asc');
query = adapter.limit(query, 10);
var results = adapter.execute(query);
printjson(results);

// API adapter
function RestAPIAdapter() {
    this.get = function(collection, id) {
        return db[collection].findOne({ _id: id });
    };
    
    this.post = function(collection, data) {
        return db[collection].insertOne(data);
    };
    
    this.put = function(collection, id, data) {
        return db[collection].updateOne({ _id: id }, { $set: data });
    };
    
    this.delete = function(collection, id) {
        return db[collection].deleteOne({ _id: id });
    };
}
Coding Round
94. Visitor pattern in MongoDB

Visitor pattern for adding operations without modifying elements.

  • Visitor: Defines operations
  • Element: Accepts visitors
  • MongoDB: Document visitor, validation visitor
  • Extensibility: Add operations easily
mongodb
// Facade pattern (MongoDB)
// Using JavaScript functions
function SubsystemA() {
    this.operationA = function() {
        print("SubsystemA: Operation");
    };
}

function SubsystemB() {
    this.operationB = function() {
        print("SubsystemB: Operation");
    };
}

function Facade() {
    this.subsystemA = new SubsystemA();
    this.subsystemB = new SubsystemB();
    
    this.operation = function() {
        this.subsystemA.operationA();
        this.subsystemB.operationB();
        print("Facade: Complex operation");
    };
}

// Usage
var facade = new Facade();
facade.operation();

// Facade with MongoDB
function DatabaseFacade() {
    this.insertUser = function(userData) {
        return db.users.insertOne({
            ...userData,
            createdAt: new Date(),
            status: 'active'
        });
    };
    
    this.findUser = function(id) {
        return db.users.findOne({ _id: id });
    };
    
    this.updateUser = function(id, userData) {
        return db.users.updateOne(
            { _id: id },
            { $set: { ...userData, updatedAt: new Date() } }
        );
    };
    
    this.deleteUser = function(id) {
        return db.users.updateOne(
            { _id: id },
            { $set: { status: 'deleted', deletedAt: new Date() } }
        );
    };
    
    this.getUserOrders = function(userId) {
        return db.orders.find({ userId: userId }).toArray();
    };
    
    this.createOrder = function(orderData) {
        return db.orders.insertOne({
            ...orderData,
            createdAt: new Date(),
            status: 'pending'
        });
    };
    
    this.getUserWithOrders = function(userId) {
        var user = this.findUser(userId);
        var orders = this.getUserOrders(userId);
        return { ...user, orders: orders };
    };
}

// Usage
var dbFacade = new DatabaseFacade();
var result = dbFacade.insertUser({ name: "Alice", age: 25 });
var user = dbFacade.findUser(result.insertedId);
var orders = dbFacade.getUserOrders(user._id);

// Analytics facade
function AnalyticsFacade() {
    this.getUserStats = function() {
        return db.users.aggregate([
            {
                $group: {
                    _id: null,
                    totalUsers: { $sum: 1 },
                    averageAge: { $avg: "$age" },
                    byCity: { $push: "$city" }
                }
            }
        ]).toArray();
    };
    
    this.getOrderStats = function() {
        return db.orders.aggregate([
            {
                $group: {
                    _id: "$status",
                    count: { $sum: 1 },
                    totalRevenue: { $sum: "$amount" }
                }
            }
        ]).toArray();
    };
    
    this.getUserActivity = function(userId) {
        return db.audit.find({ userId: userId, action: 'login' }).toArray();
    };
}

// Usage
var analytics = new AnalyticsFacade();
var userStats = analytics.getUserStats();
var orderStats = analytics.getOrderStats();
Coding Round
95. Iterator pattern in MongoDB

Iterator pattern for sequential access to collections.

  • Iterator: Traverses collection
  • Aggregate: Creates iterator
  • MongoDB: Cursor, custom iterator
  • Pagination: Page through results
mongodb
// Composite pattern (MongoDB)
// Using JavaScript functions
function Component() {
    this.operation = function() {};
}

function Leaf(name) {
    this.name = name;
    this.operation = function() {
        print("Leaf " + this.name + ": Operation");
    };
}
Leaf.prototype = Object.create(Component.prototype);

function Composite(name) {
    this.name = name;
    this.children = [];
    
    this.add = function(component) {
        this.children.push(component);
    };
    
    this.remove = function(component) {
        var index = this.children.indexOf(component);
        if (index > -1) {
            this.children.splice(index, 1);
        }
    };
    
    this.operation = function() {
        print("Composite " + this.name + ": Operation");
        this.children.forEach(function(child) {
            child.operation();
        });
    };
}
Composite.prototype = Object.create(Component.prototype);

// Usage
var leaf1 = new Leaf("A");
var leaf2 = new Leaf("B");
var composite = new Composite("Root");
composite.add(leaf1);
composite.add(leaf2);
composite.operation();

// Composite with MongoDB
function DocumentNode() {
    this.data = null;
    this.children = [];
    
    this.setData = function(data) {
        this.data = data;
    };
    
    this.addChild = function(child) {
        this.children.push(child);
    };
    
    this.toJSON = function() {
        if (this.children.length === 0) {
            return this.data;
        }
        var result = { ...this.data };
        this.children.forEach(function(child, index) {
            result['child_' + index] = child.toJSON();
        });
        return result;
    };
}

// Usage
var root = new DocumentNode();
root.setData({ name: "Root", type: "document" });

var child1 = new DocumentNode();
child1.setData({ name: "Child 1", type: "text" });

var child2 = new DocumentNode();
child2.setData({ name: "Child 2", type: "image" });

root.addChild(child1);
root.addChild(child2);

var json = root.toJSON();
printjson(json);

// Composite for database schema
function SchemaNode() {
    this.fields = {};
    this.subSchemas = {};
    
    this.addField = function(name, type, options) {
        this.fields[name] = { type: type, options: options || {} };
    };
    
    this.addSubSchema = function(name, schema) {
        this.subSchemas[name] = schema;
    };
    
    this.toMongoSchema = function() {
        var schema = {
            bsonType: "object",
            properties: {},
            required: []
        };
        
        for (var field in this.fields) {
            var fieldDef = this.fields[field];
            schema.properties[field] = {
                bsonType: fieldDef.type
            };
            if (fieldDef.options.required) {
                schema.required.push(field);
            }
        }
        
        for (var sub in this.subSchemas) {
            schema.properties[sub] = this.subSchemas[sub].toMongoSchema();
        }
        
        return schema;
    };
}

// Usage
var userSchema = new SchemaNode();
userSchema.addField('name', 'string', { required: true });
userSchema.addField('age', 'int', { required: false });
userSchema.addField('email', 'string', { required: true });

var addressSchema = new SchemaNode();
addressSchema.addField('street', 'string', { required: true });
addressSchema.addField('city', 'string', { required: true });

userSchema.addSubSchema('address', addressSchema);

var mongoSchema = userSchema.toMongoSchema();
printjson(mongoSchema);
Coding Round
96. Template Method pattern in MongoDB

Template Method for algorithm skeletons.

  • Abstract: Defines template
  • Concrete: Implements steps
  • MongoDB: Data processor, document processor
  • Hooks: before/after callbacks
mongodb
// Visitor pattern (MongoDB)
// Using JavaScript functions
function Visitor() {
    this.visit = function(element) {};
}

function Element() {
    this.accept = function(visitor) {};
}

function ElementA() {
    this.accept = function(visitor) {
        visitor.visit(this);
    };
}
ElementA.prototype = Object.create(Element.prototype);

function ElementB() {
    this.accept = function(visitor) {
        visitor.visit(this);
    };
}
ElementB.prototype = Object.create(Element.prototype);

function ConcreteVisitor() {
    this.visitA = function(element) {
        print("Visiting ElementA");
    };
    
    this.visitB = function(element) {
        print("Visiting ElementB");
    };
    
    this.visit = function(element) {
        if (element instanceof ElementA) {
            this.visitA(element);
        } else if (element instanceof ElementB) {
            this.visitB(element);
        }
    };
}

// Usage
var visitor = new ConcreteVisitor();
var elementA = new ElementA();
var elementB = new ElementB();
elementA.accept(visitor);
elementB.accept(visitor);

// Visitor with MongoDB
function DocumentVisitor() {
    this.visitInsert = function(doc) {
        print("Inserting document: " + JSON.stringify(doc));
        return db.collection.insertOne(doc);
    };
    
    this.visitUpdate = function(filter, update) {
        print("Updating documents: " + JSON.stringify(filter));
        return db.collection.updateMany(filter, { $set: update });
    };
    
    this.visitDelete = function(filter) {
        print("Deleting documents: " + JSON.stringify(filter));
        return db.collection.deleteMany(filter);
    };
    
    this.visitFind = function(filter) {
        print("Finding documents: " + JSON.stringify(filter));
        return db.collection.find(filter).toArray();
    };
}

function DocumentCollection(collection) {
    this.collection = collection;
    
    this.accept = function(visitor, operation, data) {
        switch(operation) {
            case 'insert':
                return visitor.visitInsert.call({ collection: this.collection }, data);
            case 'update':
                return visitor.visitUpdate.call({ collection: this.collection }, data.filter, data.update);
            case 'delete':
                return visitor.visitDelete.call({ collection: this.collection }, data);
            case 'find':
                return visitor.visitFind.call({ collection: this.collection }, data);
        }
    };
}

// Usage
var collection = new DocumentCollection(db.users);
var visitor = new DocumentVisitor();

collection.accept(visitor, 'insert', { name: "Alice" });
collection.accept(visitor, 'find', { name: "Alice" });

// Visitor for document validation
function ValidationVisitor() {
    this.schema = null;
    
    this.setSchema = function(schema) {
        this.schema = schema;
    };
    
    this.visit = function(doc) {
        if (!this.schema) {
            print("No schema set");
            return doc;
        }
        
        var validated = {};
        for (var field in this.schema) {
            if (this.schema[field].required && !doc[field]) {
                throw new Error("Missing required field: " + field);
            }
            validated[field] = doc[field] || this.schema[field].default;
        }
        return validated;
    };
}

// Usage
var validator = new ValidationVisitor();
validator.setSchema({
    name: { required: true, default: 'Unknown' },
    age: { required: false, default: 0 }
});

try {
    var validDoc = validator.visit({ name: "Alice" });
    printjson(validDoc);
    var invalidDoc = validator.visit({}); // Throws error
} catch (error) {
    print(error.message);
}
Coding Round
97. Builder pattern in MongoDB

Builder pattern for constructing complex objects.

  • Builder: Constructs parts
  • Director: Orchestrates construction
  • MongoDB: Query builder, document builder
  • Fluent interface: Method chaining
mongodb
// Iterator pattern (MongoDB)
// Using JavaScript functions
function Iterator(collection) {
    this.collection = collection;
    this.index = 0;
    
    this.next = function() {
        if (this.hasNext()) {
            return this.collection[this.index++];
        }
        return null;
    };
    
    this.hasNext = function() {
        return this.index < this.collection.length;
    };
}

function CustomCollection() {
    this.items = [];
    
    this.add = function(item) {
        this.items.push(item);
    };
    
    this.getIterator = function() {
        return new Iterator(this.items);
    };
}

// Usage
var collection = new CustomCollection();
collection.add("A");
collection.add("B");
collection.add("C");
var iterator = collection.getIterator();
while (iterator.hasNext()) {
    print(iterator.next());
}

// Iterator with MongoDB
function MongoIterator(collection, filter) {
    this.cursor = collection.find(filter);
    this.hasNext = function() {
        return this.cursor.hasNext();
    };
    this.next = function() {
        return this.cursor.next();
    };
}

// Usage
var iterator = new MongoIterator(db.users, { age: { $gt: 18 } });
while (iterator.hasNext()) {
    var user = iterator.next();
    print(user.name);
}

// Custom cursor iterator
function CursorIterator(collection, query) {
    this.cursor = collection.find(query).toArray();
    this.index = 0;
    
    this.next = function() {
        if (this.hasNext()) {
            return this.cursor[this.index++];
        }
        return null;
    };
    
    this.hasNext = function() {
        return this.index < this.cursor.length;
    };
}

// Usage
var iter = new CursorIterator(db.users, {});
while (iter.hasNext()) {
    var doc = iter.next();
    printjson(doc);
}

// Pagination iterator
function PaginatedIterator(collection, query, pageSize) {
    this.collection = collection;
    this.query = query;
    this.pageSize = pageSize || 10;
    this.currentPage = 0;
    this.results = [];
    this.total = 0;
    this.index = 0;
    
    this.loadPage = function() {
        this.results = this.collection.find(this.query)
            .skip(this.currentPage * this.pageSize)
            .limit(this.pageSize)
            .toArray();
        this.index = 0;
        this.total = this.collection.countDocuments(this.query);
    };
    
    this.next = function() {
        if (this.index >= this.results.length) {
            if ((this.currentPage + 1) * this.pageSize < this.total) {
                this.currentPage++;
                this.loadPage();
            } else {
                return null;
            }
        }
        return this.results[this.index++];
    };
    
    this.hasNext = function() {
        if (this.index < this.results.length) {
            return true;
        }
        return (this.currentPage + 1) * this.pageSize < this.total;
    };
    
    this.loadPage();
}

// Usage
var paginated = new PaginatedIterator(db.users, { age: { $gt: 18 } }, 5);
while (paginated.hasNext()) {
    var user = paginated.next();
    print(user.name);
}
Coding Round
98. Prototype pattern in MongoDB

Prototype pattern for cloning objects.

  • Prototype: Cloneable object
  • Clone: Creates a copy
  • MongoDB: Document prototype, template documents
  • Performance: Fast object creation
mongodb
// Template Method pattern (MongoDB)
// Using JavaScript functions
function AbstractClass() {
    this.templateMethod = function() {
        this.step1();
        this.step2();
        this.step3();
    };
    
    this.step1 = function() {
        print("Step 1");
    };
    
    this.step2 = function() {};
    
    this.step3 = function() {
        print("Step 3");
    };
}

function ConcreteClass() {
    this.step2 = function() {
        print("Concrete Step 2");
    };
}
ConcreteClass.prototype = Object.create(AbstractClass.prototype);

// Usage
var concrete = new ConcreteClass();
concrete.templateMethod();

// Template with MongoDB
function DataProcessor() {
    this.process = function(data) {
        this.validate(data);
        this.transform(data);
        this.save(data);
        this.log(data);
    };
    
    this.validate = function(data) {
        if (!data._id) {
            data._id = new ObjectId();
        }
        return data;
    };
    
    this.transform = function(data) {
        if (data.createdAt) {
            data.createdAt = new Date(data.createdAt);
        }
        return data;
    };
    
    this.save = function(data) {
        return db.collection.insertOne(data);
    };
    
    this.log = function(data) {
        print("Processed document: " + data._id);
        return data;
    };
}

// Usage
var processor = new DataProcessor();
processor.process({ name: "Alice", age: 25 });

// Template with hooks
function DocumentProcessor(collection) {
    this.collection = collection;
    this.beforeValidate = function(data) { return data; };
    this.afterValidate = function(data) { return data; };
    this.beforeSave = function(data) { return data; };
    this.afterSave = function(data) { return data; };
    
    this.process = function(data) {
        data = this.beforeValidate(data);
        data = this.validate(data);
        data = this.afterValidate(data);
        data = this.beforeSave(data);
        var result = this.save(data);
        result = this.afterSave(result);
        return result;
    };
    
    this.validate = function(data) {
        if (!data.name) {
            throw new Error("Name is required");
        }
        return data;
    };
    
    this.save = function(data) {
        return this.collection.insertOne(data);
    };
}

// Usage
var userProcessor = new DocumentProcessor(db.users);
userProcessor.beforeSave = function(data) {
    data.createdAt = new Date();
    return data;
};
userProcessor.afterSave = function(result) {
    print("User saved with ID: " + result.insertedId);
    return result;
};

userProcessor.process({ name: "Alice", age: 25 });
Coding Round
99. Database design in MongoDB

Database design principles for MongoDB including normalization and denormalization.

  • Embedded documents: One-to-one, one-to-many
  • References: Many-to-many relationships
  • Indexing: Create indexes for queries
  • Schema validation: Enforce data structure
mongodb
// Builder pattern (MongoDB)
// Using JavaScript functions
function Product() {
    this.parts = [];
    
    this.add = function(part) {
        this.parts.push(part);
    };
    
    this.listParts = function() {
        print(this.parts.join(', '));
    };
}

function Builder() {
    this.product = new Product();
    
    this.reset = function() {
        this.product = new Product();
    };
    
    this.buildStepA = function() {
        this.product.add("Part A");
    };
    
    this.buildStepB = function() {
        this.product.add("Part B");
    };
    
    this.getResult = function() {
        return this.product;
    };
}

function Director(builder) {
    this.builder = builder;
    
    this.buildMinimal = function() {
        this.builder.buildStepA();
    };
    
    this.buildFull = function() {
        this.builder.buildStepA();
        this.builder.buildStepB();
    };
}

// Usage
var builder = new Builder();
var director = new Director(builder);
director.buildMinimal();
var product = builder.getResult();
product.listParts();

// Builder with MongoDB
function QueryBuilder() {
    this.query = {};
    this.options = {};
    this.collection = null;
    
    this.from = function(collection) {
        this.collection = collection;
        return this;
    };
    
    this.where = function(filter) {
        this.query = filter;
        return this;
    };
    
    this.select = function(fields) {
        this.options.projection = {};
        fields.forEach(function(field) {
            this.options.projection[field] = 1;
        }, this);
        return this;
    };
    
    this.limit = function(count) {
        this.options.limit = count;
        return this;
    };
    
    this.skip = function(count) {
        this.options.skip = count;
        return this;
    };
    
    this.sort = function(field, direction) {
        this.options.sort = {};
        this.options.sort[field] = direction === 'desc' ? -1 : 1;
        return this;
    };
    
    this.execute = function() {
        if (!this.collection) {
            throw new Error("Collection not specified");
        }
        var cursor = this.collection.find(this.query);
        if (this.options.projection) {
            cursor = cursor.project(this.options.projection);
        }
        if (this.options.sort) {
            cursor = cursor.sort(this.options.sort);
        }
        if (this.options.limit) {
            cursor = cursor.limit(this.options.limit);
        }
        if (this.options.skip) {
            cursor = cursor.skip(this.options.skip);
        }
        return cursor.toArray();
    };
    
    this.executeOne = function() {
        return this.execute()[0] || null;
    };
}

// Usage
var query = new QueryBuilder();
var results = query
    .from(db.users)
    .where({ age: { $gt: 18 } })
    .select(['name', 'age'])
    .sort('age', 'desc')
    .limit(10)
    .execute();

printjson(results);

// Document builder
function DocumentBuilder() {
    this.doc = {};
    
    this.set = function(key, value) {
        this.doc[key] = value;
        return this;
    };
    
    this.setNested = function(path, value) {
        var parts = path.split('.');
        var current = this.doc;
        for (var i = 0; i < parts.length - 1; i++) {
            if (!current[parts[i]]) {
                current[parts[i]] = {};
            }
            current = current[parts[i]];
        }
        current[parts[parts.length - 1]] = value;
        return this;
    };
    
    this.addToArray = function(key, value) {
        if (!this.doc[key]) {
            this.doc[key] = [];
        }
        this.doc[key].push(value);
        return this;
    };
    
    this.timestamp = function() {
        this.doc.createdAt = new Date();
        this.doc.updatedAt = new Date();
        return this;
    };
    
    this.build = function() {
        return this.doc;
    };
}

// Usage
var doc = new DocumentBuilder()
    .set('name', 'Alice')
    .set('age', 25)
    .setNested('address.city', 'NYC')
    .setNested('address.zip', '10001')
    .addToArray('hobbies', 'reading')
    .addToArray('hobbies', 'gaming')
    .timestamp()
    .build();

printjson(doc);
db.users.insertOne(doc);
Coding Round
100. Query optimization in MongoDB

Query optimization techniques for MongoDB performance.

  • Indexes: Create appropriate indexes
  • Explain: Analyze query execution
  • Projection: Return only needed fields
  • Covered queries: Index-only queries
mongodb
// Prototype pattern (MongoDB)
// Using JavaScript functions
function Prototype(name, nested) {
    this.name = name;
    this.nested = nested || {};
    
    this.clone = function() {
        return new Prototype(this.name, this.nested);
    };
    
    this.deepClone = function() {
        return new Prototype(
            this.name,
            JSON.parse(JSON.stringify(this.nested))
        );
    };
}

// Usage
var original = new Prototype("Original", { value: 42 });
var copy = original.clone();
copy.name = "Copy";
copy.nested.value = 99;

print(original.name); // Original
print(original.nested.value); // 42 (shallow copy)

var deepCopy = original.deepClone();
deepCopy.nested.value = 100;
print(original.nested.value); // 42 (deep copy)

// Prototype with MongoDB
function DocumentPrototype(collection) {
    this.collection = collection;
    this.prototype = null;
    
    this.setPrototype = function(doc) {
        this.prototype = JSON.parse(JSON.stringify(doc));
        return this;
    };
    
    this.create = function(overrides) {
        if (!this.prototype) {
            throw new Error("Prototype not set");
        }
        var doc = JSON.parse(JSON.stringify(this.prototype));
        for (var key in overrides) {
            doc[key] = overrides[key];
        }
        return doc;
    };
    
    this.insert = function(overrides) {
        var doc = this.create(overrides);
        return this.collection.insertOne(doc);
    };
    
    this.load = function(id) {
        var doc = this.collection.findOne({ _id: id });
        if (doc) {
            this.setPrototype(doc);
        }
        return this;
    };
}

// Usage
var prototype = new DocumentPrototype(db.users);
prototype.setPrototype({
    name: "Default User",
    age: 0,
    status: "active",
    createdAt: new Date(),
    updatedAt: new Date()
});

var user1 = prototype.create({ name: "Alice", age: 25 });
var user2 = prototype.create({ name: "Bob", age: 30 });

db.users.insertMany([user1, user2]);

// Prototype with inheritance
function UserPrototype() {
    this.name = "Unknown";
    this.age = 0;
    this.status = "active";
    this.createdAt = new Date();
    
    this.clone = function() {
        return JSON.parse(JSON.stringify(this));
    };
    
    this.setName = function(name) {
        this.name = name;
        return this;
    };
    
    this.setAge = function(age) {
        this.age = age;
        return this;
    };
}

// Usage
var userPrototype = new UserPrototype();
var user = userPrototype.clone();
user.name = "Alice";
user.age = 25;

// Prototype with factory
function UserFactory() {
    this.prototype = new UserPrototype();
    
    this.createUser = function(name, age) {
        var user = this.prototype.clone();
        user.name = name;
        user.age = age;
        return user;
    };
}

// Usage
var factory = new UserFactory();
var alice = factory.createUser("Alice", 25);
var bob = factory.createUser("Bob", 30);
printjson(alice);
printjson(bob);