MongoDB
03 / 04

CRUD & Queries

CRUD & Queries

Core Concepts

  • Document — JSON-like record (BSON internally)

  • Collection — group of documents (like a table, but schema-less)

  • _id — auto-created ObjectId, globally unique, immutable

  • Database — namespace of collections

Insert

// mongosh / Node.js (mongodb driver)
const db = client.db('mydb');
const users = db.collection('users');

// Insert one
const result = await users.insertOne({
  name: 'Alice',
  email: 'alice@example.com',
  age: 28,
  roles: ['user'],
  address: { city: 'NYC', country: 'US' },
  createdAt: new Date(),
});
console.log(result.insertedId);  // ObjectId

// Insert many
await users.insertMany([
  { name: 'Bob', email: 'bob@example.com' },
  { name: 'Carol', email: 'carol@example.com' },
], { ordered: false });  // continue on error if false

Find & Query

// Find all
const allUsers = await users.find({}).toArray();

// Find with filter
const adults = await users.find({ age: { $gte: 18 } }).toArray();

// Find one
const user = await users.findOne({ email: 'alice@example.com' });

// Find by _id
const { ObjectId } = require('mongodb');
const user = await users.findOne({ _id: new ObjectId('64abc123...') });

// Projection (include/exclude fields)
const names = await users.find({}, { projection: { name: 1, email: 1, _id: 0 } }).toArray();

// Sort, skip, limit
const paginated = await users.find({ active: true })
  .sort({ createdAt: -1 })
  .skip(20)
  .limit(10)
  .toArray();

// Count
const count = await users.countDocuments({ age: { $gte: 18 } });

// Comparison operators
// $eq  $ne  $gt  $gte  $lt  $lte  $in  $nin
await users.find({ age: { $gte: 18, $lte: 65 } }).toArray();
await users.find({ role: { $in: ['admin', 'mod'] } }).toArray();
await users.find({ status: { $nin: ['banned', 'deleted'] } }).toArray();

// Logical operators
await users.find({
  $and: [{ age: { $gte: 18 } }, { active: true }]
}).toArray();

await users.find({
  $or: [{ email: 'a@b.com' }, { name: 'Admin' }]
}).toArray();

await users.find({ premium: { $not: { $eq: true } } }).toArray();

// Element operators
await users.find({ phone: { $exists: true } }).toArray();
await users.find({ age: { $type: 'number' } }).toArray();

// Array operators
await users.find({ roles: 'admin' }).toArray();          // contains 'admin'
await users.find({ tags: { $all: ['js', 'ts'] } }).toArray(); // contains all
await users.find({ tags: { $size: 3 } }).toArray();

// Regex
await users.find({ name: /^alice/i }).toArray();
await users.find({ name: { $regex: '^alice', $options: 'i' } }).toArray();

// Nested field
await users.find({ 'address.city': 'NYC' }).toArray();

Update

// Update one
await users.updateOne(
  { _id: userId },
  {
    $set: { name: 'Alice B.', updatedAt: new Date() },
    $inc: { loginCount: 1 },     // increment
    $push: { tags: 'premium' },  // add to array
    $pull: { tags: 'free' },     // remove from array
    $unset: { tempField: '' },   // remove field
  }
);

// Update many
await users.updateMany(
  { active: false, lastLoginAt: { $lt: new Date('2023-01-01') } },
  { $set: { status: 'inactive' } }
);

// Upsert
await users.updateOne(
  { email: 'newuser@example.com' },
  { $setOnInsert: { createdAt: new Date() }, $set: { name: 'New User' } },
  { upsert: true }
);

// findOneAndUpdate — returns the document
const updated = await users.findOneAndUpdate(
  { _id: userId },
  { $set: { lastSeen: new Date() } },
  { returnDocument: 'after' }   // return updated doc
);

// Array update operators
await users.updateOne({ _id: userId }, {
  $addToSet: { tags: 'new-tag' },          // add if not exists (like a set)
  $pop: { items: -1 },                      // remove first (-1) or last (1)
  $pullAll: { tags: ['old', 'deprecated'] } // remove multiple values
});

Delete

// Delete one
await users.deleteOne({ _id: userId });

// Delete many
await users.deleteMany({ active: false, createdAt: { $lt: cutoffDate } });

// Find and delete — returns the deleted doc
const deleted = await users.findOneAndDelete({ _id: userId });

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free