# The MongoDB basics tutorial

> Learn MongoDB basics with mongosh: install the database, create documents, query collections, update records, and delete data using modern CRUD methods.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2018-11-22 | Updated: 2026-07-18 | Topics: [Database](https://flaviocopes.com/tags/database/) | Canonical: https://flaviocopes.com/mongodb/

MongoDB is a document database.

Instead of storing data in rows and tables, it stores **documents** inside **collections**. Documents look similar to JavaScript objects, which makes MongoDB approachable if you already know JavaScript.

Here is a document:

```js
{
  name: 'Roger',
  age: 8,
  favoriteFoods: ['biscuits', 'carrots']
}
```

MongoDB stores documents as [BSON](https://www.mongodb.com/docs/manual/reference/bson-types/), a binary format that supports types such as dates, decimals, binary data, and object IDs.

## MongoDB has a flexible schema

MongoDB is often called schemaless, but **flexible schema** is more accurate.

Documents in the same collection do not need to contain the same fields by default. You can still add [schema validation](https://www.mongodb.com/docs/manual/core/schema-validation/) to require specific fields, data types, or value ranges.

This gives you flexibility while prototyping and validation when the application structure becomes stable.

## Install MongoDB on macOS

You can use MongoDB Atlas in the cloud, or run MongoDB Community Edition locally.

I use a Mac, so this tutorial installs the local server using the official MongoDB Homebrew tap:

```bash
brew tap mongodb/brew
brew install mongodb-community
```

Start MongoDB as a macOS service:

```bash
brew services start mongodb-community
```

The unversioned formula follows the latest production release offered by the official tap. Check the [MongoDB Homebrew tap](https://github.com/mongodb/homebrew-brew) and [installation guide](https://www.mongodb.com/docs/manual/administration/install-community/) if the command or macOS requirements change.

By default, a local `mongod` process binds to localhost. Do not expose it to a network without configuring authentication and following the [MongoDB security checklist](https://www.mongodb.com/docs/manual/administration/security-checklist/).

## Open the MongoDB shell

MongoDB's current shell is called `mongosh`. The old `mongo` shell used in earlier versions has been replaced.

Open a second terminal and run:

```bash
mongosh
```

The shell connects to the local server.

Run `db` to see the current database:

```js
db
```

Switch to a database called `animals`:

```js
use animals
```

This selects the database, but MongoDB does not save it until you create data.

## Insert documents

Insert one document into a `dogs` collection:

```js
db.dogs.insertOne({
  name: 'Roger',
  age: 8
})
```

MongoDB creates the collection when you first insert data. It also adds a unique `_id` field when you do not provide one.

Insert several documents at once:

```js
db.dogs.insertMany([
  { name: 'Buck', age: 4 },
  { name: 'Togo', age: 6 },
  { name: 'Balto', age: 5 }
])
```

The old `insert()` method is not the right API for new code. Use `insertOne()` or `insertMany()`.

## Find documents

Find every document in the collection:

```js
db.dogs.find()
```

`find()` returns a cursor. `mongosh` displays the first batch for you.

Pass a filter to select matching documents:

```js
db.dogs.find({ age: 5 })
```

Use `findOne()` when you need one matching document:

```js
db.dogs.findOne({ name: 'Roger' })
```

If several documents match, `findOne()` returns the first document according to the query plan. Add a unique identifier to the filter when the exact record matters.

## Update documents

Use `updateOne()` to change the first matching document:

```js
db.dogs.updateOne(
  { name: 'Roger' },
  { $set: { age: 9 } }
)
```

The first object is the filter. The second object uses the `$set` update operator to change one field.

Use `updateMany()` when every matching document should change:

```js
db.dogs.updateMany(
  { age: { $lt: 6 } },
  { $set: { young: true } }
)
```

The old `update()` method has been replaced by clearer methods such as `updateOne()`, `updateMany()`, and `replaceOne()`.

## Delete documents

Delete one matching document:

```js
db.dogs.deleteOne({ name: 'Togo' })
```

Delete every document marked as young:

```js
db.dogs.deleteMany({ young: true })
```

To remove every document from the collection, pass an empty filter:

```js
db.dogs.deleteMany({})
```

Be careful with an empty filter. The collection remains, but all its documents are deleted.

The official [MongoDB CRUD guide](https://www.mongodb.com/docs/manual/crud/) lists the current create, read, update, and delete methods.

## List databases and collections

After inserting data, list the databases:

```js
show dbs
```

List collections in the current database:

```js
show collections
```

You rarely need to create a normal collection manually. MongoDB creates it on the first insert.

Use `db.createCollection()` when you need options such as schema validation, a time-series collection, or a capped collection. See the official [`db.createCollection()` reference](https://www.mongodb.com/docs/manual/reference/method/db.createCollection/).

You now have the basic MongoDB workflow: select a database, insert documents, query them, update them, and delete them.
