Skip to content

MongoDB

Practical mongosh cheatsheet for day-to-day queries.

Connect and switch database

1
2
3
4
mongosh
show dbs
use mydb
db
Current Mongosh Log ID: 67f...
Connecting to:          mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000
MongoDB server version: 8.0.0

admin   40.00 KiB
config  72.00 KiB
local   72.00 KiB

switched to db mydb
mydb

Collections

1
2
3
show collections
db.users.drop() // delete one collection
db.dropDatabase() // delete current database

Insert documents

1
2
3
4
5
6
db.users.insertOne({ name: "Alice", age: 29, city: "Paris", tags: ["pro", "beta"] })

db.users.insertMany([
    { name: "Bob", age: 35, city: "Lyon", score: 12 },
    { name: "Chloe", age: 22, city: "Paris", score: 18 }
])
{
  acknowledged: true,
  insertedId: ObjectId("665000000000000000000001")
}
{
  acknowledged: true,
  insertedIds: {
    '0': ObjectId("665000000000000000000002"),
    '1': ObjectId("665000000000000000000003")
  }
}

Find basics

All documents

db.users.find()
db.users.find().pretty()
[
  {
    _id: ObjectId("665000000000000000000001"),
    name: 'Alice',
    age: 29,
    city: 'Paris',
    tags: [ 'pro', 'beta' ]
  },
  ...
]

Filter (where)

1
2
3
4
5
db.users.find({ city: "Paris" })
db.users.find({ age: { $gt: 30 } }) // > 30
db.users.find({ age: { $gte: 18, $lt: 30 } }) // 18 <= age < 30
db.users.find({ city: { $in: ["Paris", "Lyon"] } })
db.users.find({ city: { $ne: "Paris" } }) // !=

Logical operators

1
2
3
4
5
6
7
db.users.find({
    $and: [{ city: "Paris" }, { age: { $gte: 25 } }]
})

db.users.find({
    $or: [{ city: "Paris" }, { score: { $gte: 15 } }]
})

Projection (select fields)

db.users.find({ city: "Paris" }, { name: 1, age: 1, _id: 0 })
1
2
3
4
[
  { name: 'Alice', age: 29 },
  { name: 'Chloe', age: 22 }
]

Sort, limit, skip (pagination)

1
2
3
4
db.users.find().sort({ age: -1 }) // desc
db.users.find().sort({ age: 1, name: 1 }) // asc
db.users.find().limit(10)
db.users.find().skip(20).limit(10) // page 3 with page size 10

Find one

db.users.findOne({ name: "Alice" })
1
2
3
4
5
6
7
{
  _id: ObjectId("665000000000000000000001"),
  name: 'Alice',
  age: 29,
  city: 'Paris',
  tags: [ 'pro', 'beta' ]
}

Count

db.users.estimatedDocumentCount() // fast total estimate
db.users.countDocuments({ city: "Paris" }) // accurate with filter
3
2

Update

db.users.updateOne(
    { name: "Alice" },
    { $set: { city: "Marseille" } }
)

db.users.updateMany(
    { city: "Paris" },
    { $inc: { score: 1 } } // increment
)

db.users.updateOne(
    { name: "Bob" },
    { $unset: { oldField: "" } } // remove field
)

db.users.updateOne(
    { name: "Diane" },
    { $set: { city: "Nice", age: 31 } },
    { upsert: true } // insert if not found
)
1
2
3
4
5
6
7
8
9
{ acknowledged: true, matchedCount: 1, modifiedCount: 1, upsertedId: null }
{ acknowledged: true, matchedCount: 2, modifiedCount: 2, upsertedId: null }
{ acknowledged: true, matchedCount: 1, modifiedCount: 1, upsertedId: null }
{
  acknowledged: true,
  matchedCount: 0,
  modifiedCount: 0,
  upsertedId: ObjectId("665000000000000000000004")
}

Delete

db.users.deleteOne({ name: "Alice" })
db.users.deleteMany({ age: { $lt: 18 } })
{ acknowledged: true, deletedCount: 1 }
{ acknowledged: true, deletedCount: 0 }

Useful aggregate pipelines

Group and count by field

1
2
3
4
db.users.aggregate([
    { $group: { _id: "$city", count: { $sum: 1 } } },
    { $sort: { count: -1 } }
])
1
2
3
4
[
  { _id: 'Paris', count: 2 },
  { _id: 'Lyon', count: 1 }
]

Average / min / max

db.users.aggregate([
    {
        $group: {
            _id: "$city",
            avgAge: { $avg: "$age" },
            minAge: { $min: "$age" },
            maxAge: { $max: "$age" }
        }
    }
])
1
2
3
4
[
  { _id: 'Paris', avgAge: 25.5, minAge: 22, maxAge: 29 },
  { _id: 'Lyon', avgAge: 35, minAge: 35, maxAge: 35 }
]

Match + project + sort

1
2
3
4
5
6
db.users.aggregate([
    { $match: { age: { $gte: 18 } } },
    { $project: { _id: 0, name: 1, city: 1, age: 1 } },
    { $sort: { age: -1 } },
    { $limit: 5 }
])
1
2
3
4
5
[
  { name: 'Bob', city: 'Lyon', age: 35 },
  { name: 'Alice', city: 'Paris', age: 29 },
  { name: 'Chloe', city: 'Paris', age: 22 }
]

Unwind array field

1
2
3
4
5
db.users.aggregate([
    { $unwind: "$tags" },
    { $group: { _id: "$tags", count: { $sum: 1 } } },
    { $sort: { count: -1 } }
])
1
2
3
4
[
  { _id: 'pro', count: 1 },
  { _id: 'beta', count: 1 }
]

Distinct values

db.users.distinct("city")
[ 'Paris', 'Lyon' ]

Index basics

1
2
3
4
db.users.createIndex({ email: 1 }, { unique: true })
db.users.createIndex({ city: 1, age: -1 })
db.users.getIndexes()
db.users.dropIndex("city_1_age_-1")
1
2
3
4
5
6
7
8
email_1
city_1_age_-1
[
  { v: 2, key: { _id: 1 }, name: '_id_' },
  { v: 2, key: { email: 1 }, name: 'email_1', unique: true },
  { v: 2, key: { city: 1, age: -1 }, name: 'city_1_age_-1' }
]
{ nIndexesWas: 3, ok: 1 }

Quick introspection

db.users.findOne() // inspect shape
db.users.stats()
{
  _id: ObjectId("665000000000000000000002"),
  name: 'Bob',
  age: 35,
  city: 'Lyon',
  score: 12
}
{
  ns: 'mydb.users',
  count: 3,
  size: 312,
  avgObjSize: 104,
  storageSize: 4096,
  nindexes: 2
}

Tip

Start simple: find + projection + sort + limit solves most daily needs.

Note

Prefer countDocuments() for exact counts and estimatedDocumentCount() for quick totals.