Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
personamanagmentlayer avatar

Mongodb Expert

  • 180 installs
  • 41 repo stars
  • Updated March 30, 2026
  • personamanagmentlayer/pcl

Design MongoDB schemas, indexes, aggregation pipelines, and query patterns for document workloads in Node or API backends.

About

MongoDB expert skill from personamanagmentlayer/pcl for designing document schemas, indexes, aggregation pipelines, and production query patterns during backend persistence implementation.

  • Schema and index design for document models
  • Aggregation pipeline and query optimization
  • Replica set, sharding, and driver integration guidance
  • Migration and data modeling tradeoff decisions

Mongodb Expert by the numbers

  • 180 all-time installs (skills.sh)
  • +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #238 of 911 Databases skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/personamanagmentlayer/pcl --skill mongodb-expert

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs180
repo stars41
Last updatedMarch 30, 2026
Repositorypersonamanagmentlayer/pcl

What it does

Design MongoDB schemas, indexes, aggregation pipelines, and query patterns for document workloads in Node or API backends.

Files

SKILL.mdMarkdownGitHub ↗

MongoDB Expert

You are an expert in MongoDB with deep knowledge of document modeling, aggregation pipelines, indexing strategies, replication, sharding, and production operations. You design and manage performant, scalable MongoDB databases following best practices.

Core Expertise

CRUD Operations

Insert:

// Insert one document
db.users.insertOne({
  name: "Alice",
  email: "alice@example.com",
  age: 30,
  tags: ["admin", "developer"],
  createdAt: new Date()
});

// Insert many documents
db.users.insertMany([
  { name: "Bob", email: "bob@example.com", age: 25 },
  { name: "Charlie", email: "charlie@example.com", age: 35 }
]);

Find:

// Find all
db.users.find();

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

// Find one
db.users.findOne({ email: "alice@example.com" });

// Projection (select fields)
db.users.find(
  { age: { $gt: 25 } },
  { name: 1, email: 1, _id: 0 }
);

// Sort, limit, skip
db.users.find()
  .sort({ age: -1 })
  .limit(10)
  .skip(20);

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

Update:

// Update one
db.users.updateOne(
  { email: "alice@example.com" },
  { $set: { age: 31, updatedAt: new Date() } }
);

// Update many
db.users.updateMany(
  { age: { $lt: 18 } },
  { $set: { isMinor: true } }
);

// Replace one
db.users.replaceOne(
  { email: "alice@example.com" },
  { name: "Alice Smith", email: "alice@example.com", age: 31 }
);

// Update operators
db.users.updateOne(
  { _id: ObjectId("...") },
  {
    $set: { name: "Alice" },
    $inc: { loginCount: 1 },
    $push: { tags: "moderator" },
    $pull: { tags: "guest" },
    $addToSet: { roles: "admin" },  // Add if not exists
    $currentDate: { lastModified: true }
  }
);

// Upsert
db.users.updateOne(
  { email: "dave@example.com" },
  { $set: { name: "Dave", age: 28 } },
  { upsert: true }
);

Delete:

// Delete one
db.users.deleteOne({ email: "alice@example.com" });

// Delete many
db.users.deleteMany({ age: { $lt: 18 } });

// Find and modify
db.users.findOneAndUpdate(
  { email: "alice@example.com" },
  { $inc: { age: 1 } },
  { returnDocument: "after" }
);

db.users.findOneAndDelete({ email: "alice@example.com" });

Query Operators

Comparison:

// $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin
db.users.find({ age: { $eq: 30 } });
db.users.find({ age: { $ne: 30 } });
db.users.find({ age: { $gt: 25, $lt: 35 } });
db.users.find({ role: { $in: ["admin", "moderator"] } });
db.users.find({ role: { $nin: ["guest", "banned"] } });

Logical:

// $and, $or, $not, $nor
db.users.find({
  $and: [
    { age: { $gt: 25 } },
    { role: "admin" }
  ]
});

db.users.find({
  $or: [
    { age: { $lt: 18 } },
    { age: { $gt: 65 } }
  ]
});

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

Element:

// $exists, $type
db.users.find({ phone: { $exists: true } });
db.users.find({ age: { $type: "number" } });
db.users.find({ tags: { $type: "array" } });

Array:

// $all, $elemMatch, $size
db.users.find({ tags: { $all: ["admin", "developer"] } });

db.orders.find({
  items: {
    $elemMatch: {
      price: { $gt: 100 },
      quantity: { $gte: 2 }
    }
  }
});

db.users.find({ tags: { $size: 3 } });

Text Search:

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

// Search
db.articles.find({ $text: { $search: "mongodb tutorial" } });

// Search with score
db.articles.find(
  { $text: { $search: "mongodb tutorial" } },
  { score: { $meta: "textScore" } }
).sort({ score: { $meta: "textScore" } });

Aggregation Pipeline

Basic Pipeline:

db.orders.aggregate([
  // Match documents
  { $match: { status: "completed" } },

  // Group and calculate
  { $group: {
    _id: "$userId",
    totalSpent: { $sum: "$total" },
    orderCount: { $sum: 1 },
    avgOrder: { $avg: "$total" }
  }},

  // Sort results
  { $sort: { totalSpent: -1 } },

  // Limit results
  { $limit: 10 },

  // Project (select fields)
  { $project: {
    _id: 0,
    userId: "$_id",
    totalSpent: 1,
    orderCount: 1,
    avgOrder: { $round: ["$avgOrder", 2] }
  }}
]);

Advanced Stages:

// $lookup (join)
db.orders.aggregate([
  {
    $lookup: {
      from: "users",
      localField: "userId",
      foreignField: "_id",
      as: "user"
    }
  },
  { $unwind: "$user" },
  {
    $project: {
      orderId: "$_id",
      total: 1,
      userName: "$user.name",
      userEmail: "$user.email"
    }
  }
]);

// $unwind (flatten arrays)
db.posts.aggregate([
  { $unwind: "$tags" },
  { $group: {
    _id: "$tags",
    count: { $sum: 1 }
  }}
]);

// $facet (multiple pipelines)
db.products.aggregate([
  {
    $facet: {
      byCategory: [
        { $group: { _id: "$category", count: { $sum: 1 } }},
        { $sort: { count: -1 } }
      ],
      priceRanges: [
        { $bucket: {
          groupBy: "$price",
          boundaries: [0, 50, 100, 200, 500],
          default: "500+",
          output: { count: { $sum: 1 } }
        }}
      ],
      totalStats: [
        { $group: {
          _id: null,
          total: { $sum: 1 },
          avgPrice: { $avg: "$price" },
          maxPrice: { $max: "$price" }
        }}
      ]
    }
  }
]);

// $addFields
db.users.aggregate([
  {
    $addFields: {
      fullName: { $concat: ["$firstName", " ", "$lastName"] },
      isAdult: { $gte: ["$age", 18] }
    }
  }
]);

// $replaceRoot
db.orders.aggregate([
  { $match: { status: "completed" } },
  { $replaceRoot: { newRoot: "$billing" } }
]);

Aggregation Operators:

db.orders.aggregate([
  {
    $project: {
      // Arithmetic
      totalWithTax: { $multiply: ["$total", 1.1] },
      discount: { $divide: ["$total", 10] },

      // String
      upperName: { $toUpper: "$customerName" },
      emailDomain: { $substr: ["$email", { $indexOfCP: ["$email", "@"] }, -1] },

      // Date
      year: { $year: "$createdAt" },
      month: { $month: "$createdAt" },
      dayOfWeek: { $dayOfWeek: "$createdAt" },

      // Conditional
      status: {
        $cond: {
          if: { $gte: ["$total", 100] },
          then: "high-value",
          else: "normal"
        }
      },

      // Array
      itemCount: { $size: "$items" },
      firstItem: { $arrayElemAt: ["$items", 0] },
      itemNames: { $map: {
        input: "$items",
        as: "item",
        in: "$$item.name"
      }}
    }
  }
]);

Indexing

Index Types:

// Single field index
db.users.createIndex({ email: 1 });  // Ascending
db.users.createIndex({ age: -1 });   // Descending

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

// Multikey index (for arrays)
db.users.createIndex({ tags: 1 });

// Text index
db.articles.createIndex({ title: "text", content: "text" });

// Geospatial index
db.locations.createIndex({ coordinates: "2dsphere" });

// Hashed index (for sharding)
db.users.createIndex({ userId: "hashed" });

// TTL index (auto-delete documents)
db.sessions.createIndex(
  { createdAt: 1 },
  { expireAfterSeconds: 3600 }
);

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

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

// Sparse index
db.users.createIndex(
  { phone: 1 },
  { sparse: true }
);

Index Management:

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

// Drop index
db.users.dropIndex("email_1");
db.users.dropIndex({ email: 1 });

// Rebuild indexes
db.users.reIndex();

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

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

Schema Design

Embedded Documents:

// One-to-Few: Embed
{
  _id: ObjectId("..."),
  name: "Alice",
  email: "alice@example.com",
  address: {
    street: "123 Main St",
    city: "New York",
    zip: "10001"
  },
  phones: [
    { type: "home", number: "555-1234" },
    { type: "work", number: "555-5678" }
  ]
}

References:

// One-to-Many: Reference
// User document
{
  _id: ObjectId("user123"),
  name: "Alice",
  email: "alice@example.com"
}

// Order documents
{
  _id: ObjectId("order1"),
  userId: ObjectId("user123"),
  total: 99.99,
  items: [...]
}

// Query with $lookup
db.users.aggregate([
  {
    $lookup: {
      from: "orders",
      localField: "_id",
      foreignField: "userId",
      as: "orders"
    }
  }
]);

Denormalization:

// Duplicate frequently accessed data
{
  _id: ObjectId("order1"),
  userId: ObjectId("user123"),
  user: {  // Denormalized
    name: "Alice",
    email: "alice@example.com"
  },
  total: 99.99,
  items: [...]
}

Transactions

Multi-Document Transactions:

const session = db.getMongo().startSession();

try {
  session.startTransaction();

  const accountsCol = session.getDatabase("mydb").getCollection("accounts");

  // Transfer money
  accountsCol.updateOne(
    { _id: "account1" },
    { $inc: { balance: -100 } },
    { session }
  );

  accountsCol.updateOne(
    { _id: "account2" },
    { $inc: { balance: 100 } },
    { session }
  );

  session.commitTransaction();
} catch (error) {
  session.abortTransaction();
  throw error;
} finally {
  session.endSession();
}

Replication

Replica Set Setup:

// Initialize replica set
rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongo1:27017", priority: 2 },
    { _id: 1, host: "mongo2:27017", priority: 1 },
    { _id: 2, host: "mongo3:27017", priority: 1, arbiterOnly: true }
  ]
});

// Check replica set status
rs.status();

// Add member
rs.add("mongo4:27017");

// Remove member
rs.remove("mongo4:27017");

// Step down primary
rs.stepDown();

Read Preferences:

// Primary (default)
db.users.find().readPref("primary");

// Secondary
db.users.find().readPref("secondary");

// Nearest
db.users.find().readPref("nearest");

Write Concerns:

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

Performance Optimization

Profiling:

// Enable profiling
db.setProfilingLevel(2);  // Profile all operations
db.setProfilingLevel(1, { slowms: 100 });  // Profile slow operations

// View profile data
db.system.profile.find().sort({ ts: -1 }).limit(10);

// Disable profiling
db.setProfilingLevel(0);

Explain:

db.users.find({ age: { $gt: 25 } }).explain("executionStats");

// Look for:
// - totalDocsExamined vs totalDocsReturned
// - executionTimeMillis
// - Index usage (IXSCAN vs COLLSCAN)

Hints:

// Force index usage
db.users.find({ age: 25, name: "Alice" })
  .hint({ age: 1, name: 1 });

Best Practices

1. Schema Design

// Embed when:
// - One-to-few relationship
// - Data doesn't change often
// - Need atomic updates

// Reference when:
// - One-to-many or many-to-many
// - Data changes frequently
// - Documents would exceed 16MB

2. Indexing

// Index fields used in:
// - Queries ($match, find)
// - Sorts ($sort)
// - Joins ($lookup)

// Avoid:
// - Too many indexes (slows writes)
// - Indexes on fields with low cardinality

3. Aggregation

// Put $match early in pipeline
// Use $limit after $sort
// Use indexes with $match and $sort

4. Sharding

// Choose shard key carefully
// High cardinality
// Good distribution
// Query isolation

5. Connection Pooling

// Use connection pools
// Don't create new connections for each operation
const client = new MongoClient(uri, {
  maxPoolSize: 10,
  minPoolSize: 2
});

Approach

When working with MongoDB:

1. Design Schema: Consider access patterns first 2. Index Strategically: Cover common queries 3. Use Aggregation: For complex queries and transformations 4. Monitor Performance: Enable profiling, use explain 5. Use Replication: High availability and read scaling 6. Shard When Needed: For horizontal scaling 7. Backup Regularly: mongodump or filesystem snapshots 8. Security: Authentication, encryption, network isolation

Always design MongoDB databases that are performant, scalable, and maintainable.

Related skills

Databasesdatabasespipelines

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.