DocsHub
CRUD Operations

Read

Learn how to read documents from MongoDB using find, findOne, filtering, projection, sorting, and limiting results.

Read

The second operation in CRUD is Read — fetching documents from a collection. MongoDB gives you two methods for this:

  • findOne() — fetch a single document
  • find() — fetch multiple documents

These two methods are the foundation of every query you will ever write in MongoDB.


findOne

findOne() returns the first document that matches your filter. If no document matches, it returns null.

Syntax

db.collection.findOne(filter)

Example — Find one student by name

db.students.findOne({ name: "Ali Hassan" })

Result

{
  _id: ObjectId("64a1f2c3e4b0a1b2c3d4e5f6"),
  name: "Ali Hassan",
  age: 16,
  grade: "10th",
  subjects: ["Math", "Physics", "English"],
  enrolled: true,
  enrollmentDate: ISODate("2024-09-01T00:00:00.000Z"),
  address: { city: "Lahore", country: "Pakistan" }
}

Find by _id

The most common use of findOne() is finding a document by its _id:

const { ObjectId } = require('mongodb');

db.students.findOne({
  _id: new ObjectId("64a1f2c3e4b0a1b2c3d4e5f6")
})

Always wrap the _id string in new ObjectId(). Passing a plain string will not find anything because a string and an ObjectId are different types in MongoDB.


find

find() returns all documents that match your filter. If you pass no filter, it returns every document in the collection.

Syntax

db.collection.find(filter)

Example — Find all students

db.students.find()

Example — Find all 10th grade students

db.students.find({ grade: "10th" })

Result

[
  {
    _id: ObjectId("64a1f2c3e4b0a1b2c3d4e5f6"),
    name: "Ali Hassan",
    age: 16,
    grade: "10th",
    subjects: ["Math", "Physics", "English"],
    enrolled: true
  },
  {
    _id: ObjectId("64a1f2c3e4b0a1b2c3d4e5f9"),
    name: "Bilal Ahmed",
    age: 16,
    grade: "10th",
    subjects: ["Physics", "Math", "Urdu"],
    enrolled: false
  }
]

Example — Find all enrolled students

db.students.find({ enrolled: true })

Example — Find by multiple fields

When you pass multiple fields in the filter, MongoDB returns only documents that match all of them:

// Students in 10th grade AND enrolled
db.students.find({
  grade: "10th",
  enrolled: true
})

Filtering Nested Fields

To filter by a field inside an embedded document, use dot notation:

// Find students from Lahore
db.students.find({ "address.city": "Lahore" })

Always wrap the dot notation path in quotes.


Filtering Array Fields

To find documents where an array contains a specific value, just use the value directly in the filter:

// Find students who take Math
db.students.find({ subjects: "Math" })

MongoDB checks if "Math" exists anywhere in the subjects array. You do not need any special operator for this.


Projection

By default, find() returns every field in each document. Projection lets you choose which fields to include or exclude.

Syntax

db.collection.find(filter, projection)

Include specific fields

Pass 1 for fields you want to include. The _id is always included unless you explicitly exclude it:

// Return only name and grade
db.students.find(
  { grade: "10th" },
  { name: 1, grade: 1 }
)

Result

[
  { _id: ObjectId("..."), name: "Ali Hassan", grade: "10th" },
  { _id: ObjectId("..."), name: "Bilal Ahmed", grade: "10th" }
]

Exclude specific fields

Pass 0 for fields you want to exclude:

// Return everything except address and enrollmentDate
db.students.find(
  { grade: "10th" },
  { address: 0, enrollmentDate: 0 }
)

Exclude _id

// Return only name and grade, no _id
db.students.find(
  { grade: "10th" },
  { name: 1, grade: 1, _id: 0 }
)

You cannot mix include and exclude in the same projection — for example { name: 1, age: 0 } is not allowed. The only exception is _id — you can always explicitly set _id: 0 even when including other fields.


Sorting Results

Use .sort() to control the order of results. Pass 1 for ascending and -1 for descending:

// Sort students by age — youngest first
db.students.find().sort({ age: 1 })

// Sort students by age — oldest first
db.students.find().sort({ age: -1 })

// Sort by grade ascending, then by name ascending
db.students.find().sort({ grade: 1, name: 1 })

Limiting Results

Use .limit() to control how many documents are returned:

// Return only 3 students
db.students.find().limit(3)

Skipping Results

Use .skip() to skip a number of documents — useful for pagination:

// Skip the first 5 students, return the next 5
db.students.find().skip(5).limit(5)

Chaining sort, limit, and skip

You can chain these methods together:

// Get the top 3 oldest students in 10th grade
db.students
  .find({ grade: "10th" })
  .sort({ age: -1 })
  .limit(3)
// Page 2 of students — 5 per page, sorted by name
db.students
  .find({ enrolled: true })
  .sort({ name: 1 })
  .skip(5)
  .limit(5)

MongoDB always applies sort first, then skip, then limit — regardless of the order you chain them in your code. So .find().limit(5).skip(2).sort({ age: 1 }) gives the same result as .find().sort({ age: 1 }).skip(2).limit(5).


Counting Documents

To count how many documents match a filter, use countDocuments():

// How many students are enrolled?
db.students.countDocuments({ enrolled: true })
// How many students are in 10th grade?
db.students.countDocuments({ grade: "10th" })

In Node.js

In a Node.js app, find() returns a cursor — not an array directly. Call .toArray() to get all results as an array:

const db = client.db('school');
const students = db.collection('students');

// findOne — returns a single document directly
const student = await students.findOne({ name: "Ali Hassan" });
console.log(student);

// find — returns a cursor, call toArray() to get results
const tenthGrade = await students
  .find({ grade: "10th" })
  .sort({ name: 1 })
  .limit(10)
  .toArray();

console.log(tenthGrade);

// countDocuments
const enrolledCount = await students.countDocuments({ enrolled: true });
console.log(`Enrolled students: ${enrolledCount}`);

School System Queries

Here are some useful queries for our school system that combine everything we covered:

// All enrolled students, sorted by name, showing only name and grade
db.students.find(
  { enrolled: true },
  { name: 1, grade: 1, _id: 0 }
).sort({ name: 1 })

// All students from Lahore in 10th grade
db.students.find({
  grade: "10th",
  "address.city": "Lahore"
})

// The 5 youngest students
db.students
  .find({ enrolled: true })
  .sort({ age: 1 })
  .limit(5)

// Find one teacher who teaches Math
db.teachers.findOne({ subject: "Math" })

// All active teachers, showing only name and subject
db.teachers.find(
  { active: true },
  { name: 1, subject: 1, _id: 0 }
)

findOne vs find

findOnefind
ReturnsOne document or nullCursor of all matching documents
Use whenYou need one specific documentYou need multiple documents
In Node.jsReturns document directlyCall .toArray() to get results
SpeedStops after first matchScans all matching documents

Use findOne() whenever you know you only need one document — like finding by _id or by a unique field. It is faster than find() because MongoDB stops searching as soon as it finds the first match.

On this page