Basic CRUD Operations

 

MongoDB CRUD Operations: A Practical Beginner’s Guide

Most applications need to store information, retrieve it, change it, and remove it. These four activities are known as CRUD: Create, Read, Update, and Delete.

This tutorial introduces MongoDB CRUD operations through a small practice database. You’ll create user records, search documents, update nested fields, and delete selected data.

Before You Begin

You need access to a running MongoDB server and the MongoDB Shell, mongosh. The examples below are shell commands, rather than code for a Node.js application.

For a local server running on the default port, open your terminal and connect with:

mongosh "mongodb://localhost:27017"

For MongoDB Atlas, use the shell connection instructions provided by your cluster. The server must be available before you can connect. MongoDB Shell documentation

Use a new practice database for these examples. Run each insertion once so you don’t create duplicate sample records.

Understand MongoDB’s Structure

MongoDB organizes data into databases, collections, and documents:

  • A database holds collections.

  • A collection holds documents.

  • A document contains fields and values, including nested objects and arrays.

For example, a blogging application might store user profiles in a users collection and articles in a posts collection.

Select a practice database:

use crud_practice

This selects the database even if it does not exist yet. MongoDB creates it when you first store data. A collection can also be created automatically by the first insertion. Databases and collections

Create: Insert Documents

Insert One User

Use insertOne() to add a single document:

db.users.insertOne({
  name: "Alex",
  email: "alex@example.com",
  address: {
    city: "New York",
    street: "Wall Street"
  },
  hobbies: ["soccer", "programming"]
})

The document contains text fields, an embedded address document, and a hobbies array.

A successful result includes acknowledged: true and an insertedId. When you omit _id, MongoDB supplies an identifier.

Insert Multiple Users

Use insertMany() with an array of documents:

db.users.insertMany([
  {
    name: "Sam",
    email: "sam@example.com",
    address: {
      city: "Chicago",
      street: "Lake Street"
    },
    hobbies: ["swimming", "reading"]
  },
  {
    name: "Jamie",
    email: "jamie@example.com",
    address: {
      city: "Los Angeles",
      street: "Main Street"
    },
    hobbies: ["exercise"]
  }
])

The result includes the identifiers of the inserted documents. MongoDB insertion methods

You can now inspect the database and its collections:

show dbs
show collections

Read: Find Documents

Retrieve All Users

An empty filter matches every document in the collection:

db.users.find({})

Find One User

Use a filter to select documents by a field value:

db.users.findOne({
  email: "alex@example.com"
})

findOne() returns one matching document, or null if there is no match.

Filter by a Nested Field

Use dot notation to access a field inside an embedded document:

db.users.find({
  "address.city": "Chicago"
})

This returns users whose address contains the city "Chicago". These examples use MongoDB’s standard CRUD query methods. MongoDB CRUD documentation

Update: Change Existing Documents

Update One Nested Field

Suppose Alex moves to Austin. Use updateOne() with $set:

db.users.updateOne(
  { email: "alex@example.com" },
  {
    $set: {
      "address.city": "Austin"
    }
  }
)

The filter selects the user. The update changes only address.city, preserving address.street.

Verify the change:

db.users.findOne({
  email: "alex@example.com"
})

The address should now contain:

{
  city: "Austin",
  street: "Wall Street"
}

Avoid Replacing an Embedded Document Accidentally

These two update expressions have different effects.

Updating one nested field:

{ $set: { "address.city": "Austin" } }

Replacing the entire address value:

{ $set: { address: { city: "Austin" } } }

The second expression removes the existing street field because the new address object contains only city.

An update result reports matchedCount and modifiedCount. A document may match without being modified if it already contains the requested value. MongoDB updateOne() reference

Update Multiple Users

Add a relationship status to every user:

db.users.updateMany(
  {},
  {
    $set: {
      relationshipStatus: "unknown"
    }
  }
)

Then change Alex’s status:

db.users.updateOne(
  { email: "alex@example.com" },
  {
    $set: {
      relationshipStatus: "single"
    }
  }
)

Inspect the users:

db.users.find({})

If you followed the examples in order, Alex has a status of "single", while Sam and Jamie have "unknown". MongoDB CRUD documentation

Replace an Entire Document

Use replaceOne() when you intend to replace a document’s contents rather than update selected fields:

db.users.replaceOne(
  { email: "jamie@example.com" },
  {
    name: "Jamie",
    email: "jamie@example.com",
    address: {
      city: "Seattle",
      street: "Pine Street"
    },
    hobbies: ["exercise", "photography"],
    relationshipStatus: "unknown"
  }
)

Fields omitted from the replacement are removed. The existing _id is preserved when it is omitted from the replacement document. MongoDB replaceOne() reference

Query Arrays and Select Returned Fields

Create a few sample posts:

db.posts.insertMany([
  {
    title: "Learning MongoDB",
    body: "An introduction to document databases.",
    author: "Alex",
    tags: ["mongodb", "learning"]
  },
  {
    title: "Swimming Basics",
    body: "Tips for beginner swimmers.",
    author: "Sam",
    tags: ["swimming", "fitness"]
  },
  {
    title: "Weekend Activities",
    body: "Ideas for an active weekend.",
    author: "Jamie",
    tags: ["swimming", "travel"]
  }
])

Match an Array Element

To find posts containing "swimming" in their tags:

db.posts.find({
  tags: "swimming"
})

This matches the second and third posts even though their arrays contain additional values.

To match an array containing exactly one element, "swimming", use:

db.posts.find({
  tags: ["swimming"]
})

That query matches none of these sample posts. Equality against an array requires the same elements in the same order. MongoDB array queries

Return Only Selected Fields

A projection controls which fields appear in query results.

Return the author of each post tagged "swimming":

db.posts.find(
  { tags: "swimming" },
  { author: 1, _id: 0 }
)

The results contain:

{ author: "Sam" }
{ author: "Jamie" }

Here, author: 1 includes the author field, and _id: 0 excludes the identifier. _id is included by default unless explicitly excluded. MongoDB projection documentation

Delete: Remove Documents

Delete One User

Remove Jamie’s record:

db.users.deleteOne({
  email: "jamie@example.com"
})

The result reports deletedCount. A value of 1 means one document was removed; 0 means nothing matched.

Check the remaining records:

db.users.find({})

Delete Multiple Users

Before deleting a group of records, inspect the filter’s matches:

db.users.find({
  relationshipStatus: "unknown"
})

Then delete those matching records:

db.users.deleteMany({
  relationshipStatus: "unknown"
})

If you followed the tutorial in order, this removes Sam. Alex remains because his status is "single".

An empty filter passed to deleteMany() removes every document in the collection. Always check the filter before running a deletion. MongoDB deletion reference

CRUD Method Reference

Operation Method Purpose
Create insertOne() Insert one document
Create insertMany() Insert multiple documents
Read find() Retrieve matching documents
Read findOne() Retrieve one matching document
Update updateOne() Update one matching document
Update updateMany() Update matching documents
Update replaceOne() Replace one matching document
Delete deleteOne() Delete one matching document
Delete deleteMany() Delete matching documents

Practice Exercise

Create a separate products collection and practice the same workflow:

  1. Insert three products with names, prices, and category arrays.

  2. Find products belonging to one category.

  3. Update one product’s price using $set.

  4. Return only product names and prices with a projection.

  5. Inspect a selected product, then delete it.

This exercise connects the individual commands into a workflow you can reuse when building an application.