10 Topics
Chapter•120 Minutes

MongoDB Installation, Setup, and Environment Configuration

Set up MongoDB using MongoDB Atlas, MongoDB Community Server, or Docker. Learn mongosh, connection strings, authentication, database selection, environment configuration, connection troubleshooting, and how to establish a repeatable development environment.

Understanding MongoDB Deployment Options

Level:BeginnerFocus:Environment setup

Before installing MongoDB, understand the different ways you can run it. MongoDB can be used as a locally managed database server, a containerized development service, or a managed cloud deployment.

1. MongoDB Atlas

MongoDB Atlas is a managed database service. You provision a database deployment, configure network access and database users, and connect using a connection string.

Atlas is convenient when developing applications that need a remotely accessible database without requiring you to maintain the underlying database server yourself.

Typical uses include:

  • Connecting a local Node.js application to a cloud database.
  • Hosting development and production databases.
  • Learning how database access restrictions and credentials work.
  • Practicing database administration through a managed interface.

Official resource: https://www.mongodb.com/products/platform/atlas-database

2. MongoDB Community Server

MongoDB Community Server allows you to run MongoDB on your own machine or on infrastructure that you administer.

It is useful for:

  • Practicing queries without relying on an internet connection.
  • Understanding how a MongoDB server runs.
  • Developing applications against a local database.
  • Testing data models before deploying them elsewhere.

Official resource: https://www.mongodb.com/try/download/community

3. MongoDB with Docker

Docker allows you to run MongoDB inside a container. A container can make the development environment reproducible across machines.

A persistent Docker volume is important because container filesystems are not a substitute for deliberate data persistence. Removing a container does not remove a separately managed named volume, but removing the volume destroys the data stored in it.

4. MongoDB Shell

mongosh is the interactive command-line shell for MongoDB. It allows you to connect to a server, select databases, execute queries, inspect collections, and run supported administrative commands.

Official resource: https://www.mongodb.com/docs/mongodb-shell/

Which option should you choose?

For a beginner, Atlas is convenient if you prefer a managed service. A local server is useful when you want direct control, and Docker is useful when you want a repeatable development environment.

You do not need to install all three. Choose one working environment and use it throughout the initial chapters.

Compare MongoDB environments
Atlas: Managed cloud deployment
Convenient when you do not want to administer the database server.
Community Server: Self-managed database server
Useful for local development and learning server configuration.
Docker: Containerized database
Useful for reproducible development and isolated environments.
mongosh: Interactive database shell
Used to execute commands against a MongoDB deployment.
Keep development and production separate

Use a dedicated development database. Never experiment with destructive operations against production data.

Key Takeaways
  • MongoDB can run locally, in Docker, or through a managed service.
  • Atlas manages the underlying database infrastructure for you.
  • Docker can provide repeatable development environments.
  • mongosh is the primary command-line tool used in this course.
  • Choose an environment that fits your learning needs rather than installing everything.
Knowledge Check

Which tool is specifically designed to provide an interactive command-line interface for MongoDB?

Setting Up a MongoDB Atlas Deployment

MongoDB Atlas allows you to create a cloud-hosted MongoDB deployment without installing the database server on your computer.

Step 1: Create an Atlas account

Visit https://www.mongodb.com/products/platform/atlas-database and follow the account creation instructions.

After signing in, create or select a project for your learning environment.

Step 2: Create a database deployment

Use the Atlas interface to create a deployment. Available deployment types, regions, and pricing depend on the current Atlas offerings and your account.

Choose a suitable region and deployment size for your learning workload. Do not assume that a particular tier or feature will always be free or available in every region.

Step 3: Create a database user

Create a database user with a username and strong password.

A database user is distinct from your Atlas website login. The database user is used to authenticate database connections.

For learning, grant only the privileges needed for your exercises. Avoid using administrative credentials in a public-facing application.

Step 4: Configure network access

Configure the deployment's network access rules to allow connections from your development environment.

If you connect from your computer, use your current public IP address when appropriate. If your network changes, the permitted address may also need updating.

Avoid allowing access from every IP address as a permanent production configuration. Network restrictions should be combined with authentication and appropriate permissions.

Step 5: Obtain a connection string

Open the deployment's connection instructions and choose the appropriate connection method.

A typical SRV connection string has this general form:

mongodb+srv://<username>:<password>@<cluster-host>/<database>?retryWrites=true&w=majority

This is a template, not a working connection string. Replace the placeholders with the values supplied by Atlas.

The SRV format uses DNS records to discover the servers associated with the deployment. It is commonly used with Atlas.

Step 6: Connect with mongosh

If mongosh is installed, you can connect using the connection string supplied by Atlas:

mongosh "mongodb+srv://<cluster-host>/learning"

The command above is illustrative. Supply your actual hostname and follow the authentication instructions for your deployment. Do not put a real password in a command that may be saved in shell history or exposed in process listings.

You can also use the Atlas-provided connection command and enter credentials when prompted, where supported.

Step 7: Verify the connection

After connecting, run:

db.runCommand({ ping: 1 });

A successful response includes ok: 1.

Then select a practice database:

use mongodb_course_lab

Insert a document to verify write access:

db.setupCheck.insertOne({
 message: "MongoDB connection verified",
 checkedAt: new Date()
});

If the insert fails, the connection may still be valid but the database user may not have the required write privileges.

Protect database credentials

Never commit a connection string containing a real password to GitHub, expose it through a NEXT_PUBLIC_ environment variable, or embed it in browser-side JavaScript.

Verify an Atlas connection
db.runCommand({ ping: 1 });

use mongodb_course_lab

db.setupCheck.insertOne({
 message: "MongoDB connection verified",
 checkedAt: new Date()
});

db.setupCheck.find();
💡 The ping command verifies that the connected deployment responds to a database command. The insert then checks whether the authenticated user can write to the selected database. Finally, find() reads the inserted document. A successful ping alone does not guarantee that the user has permission to perform every operation.
Key Takeaways
  • An Atlas account and a MongoDB database user serve different purposes.
  • Network access rules control which client networks can reach the deployment.
  • Authentication and authorization are separate from network access.
  • A successful ping verifies connectivity but not every required permission.
  • Connection strings should be stored securely.
Knowledge Check

What does a successful `{ ping: 1 }` command establish?

Installing MongoDB Community Server Locally

A local MongoDB server gives you direct control over the database process and is useful for learning without depending on a remote deployment.

Step 1: Download MongoDB Community Server

Visit the official download page:

https://www.mongodb.com/try/download/community

Select the appropriate operating system and installation package. Follow the installation instructions for your platform.

Step 2: Install mongosh

MongoDB Shell is distributed separately from the database server in many installation workflows. Verify that mongosh is installed and available in your terminal.

mongosh --version

If the terminal reports that the command cannot be found, check the installation and PATH configuration.

Step 3: Start the database server

The startup procedure depends on the operating system and installation method.

On systems configured with a service manager, MongoDB may run as a service. On other setups, you may need to start the server process manually with a configured data directory.

Do not assume the server is running simply because the installation completed.

Step 4: Connect to the server

If the server is running locally on the default port and does not require authentication, connect using:

mongosh "mongodb://127.0.0.1:27017"

127.0.0.1 refers to the local machine. The default MongoDB server port is 27017 unless the deployment has been configured differently.

Step 5: Verify the server

db.runCommand({ ping: 1 });

If the connection is successful, continue with the practice database:

use mongodb_course_lab

db.installationCheck.insertOne({
 status: "ready",
 createdAt: new Date()
});

Understanding server and shell processes

The database server and shell are different processes:

  • mongod is the MongoDB database server process.
  • mongosh is the interactive shell client.

Starting mongosh does not necessarily start mongod. If the server is stopped or unreachable, the shell cannot establish a connection.

Common local connection problems

If a connection fails, check whether the server is running, whether the port matches the server configuration, whether a firewall is blocking the connection, and whether authentication is required.

Also verify that the server is using the data directory you expect. Accidentally starting multiple database processes with conflicting ports or data directories can cause confusion and operational problems.

Check your local MongoDB server
db.runCommand({ ping: 1 });

db.serverStatus().version;

db.getMongo();
💡 The ping command verifies that the server responds. serverStatus() returns server status information, including the version, when the user has permission to run it. getMongo() displays the current connection object in mongosh. Some diagnostic commands require additional privileges.
Key Takeaways
  • MongoDB Community Server can run on your local machine.
  • mongod is the database server process; mongosh is the shell client.
  • The default MongoDB server port is 27017.
  • The server must be running before a shell client can connect.
  • Installation and startup procedures differ across operating systems.
Knowledge Check

What is the primary difference between mongod and mongosh?

Running MongoDB with Docker

Docker provides a repeatable way to run MongoDB in a container. This is particularly useful when several developers need the same database version and local configuration.

The following example binds the MongoDB port to the loopback interface so that the service is reachable from the host machine without being published on every network interface.

Step 1: Create a persistent volume

docker volume create mongodb-course-data

A named volume stores database files separately from the container's writable layer.

Step 2: Start the container

docker run -d \
 --name mongodb-course \
 -p 127.0.0.1:27017:27017 \
 -e MONGO_INITDB_ROOT_USERNAME=courseadmin \
 -e MONGO_INITDB_ROOT_PASSWORD=local-dev-password-change-me \
 -v mongodb-course-data:/data/db \
 mongo:8.0

This command is intended for local development. The sample credentials must not be reused in production.

The official image initializes the root user when initializing a fresh database directory. If you reuse an existing volume, changing the initialization environment variables does not automatically change the password of an already-created user.

For repeatable team environments, pin a specific image version and, when required by your operational process, a verified image digest. Review the official image documentation for version-specific behavior.

Step 3: Inspect the container

docker ps

This lists running containers. To inspect MongoDB startup logs:

docker logs mongodb-course

Step 4: Connect with mongosh

If mongosh is installed on your host:

mongosh "mongodb://courseadmin:local-dev-password-change-me@127.0.0.1:27017/admin?authSource=admin"

The URI authenticates the user against the admin database. The command includes the example password for demonstration only; avoid passing real secrets through shell commands that may be recorded in history.

Step 5: Test persistence

Insert a document:

use mongodb_course_lab

db.dockerCheck.insertOne({
 message: "Persisted in a Docker volume",
 createdAt: new Date()
});

Stop and remove the container:

docker stop mongodb-course
docker rm mongodb-course

Start a new container using the same volume and configuration. The previously inserted document should remain because the data is stored in the named volume.

Important distinction: container versus volume

Removing a container is different from removing a volume. The following command removes the volume and permanently deletes the data stored in that volume when removal succeeds:

docker volume rm mongodb-course-data

Do not execute it if you need the data.

Official image documentation: https://hub.docker.com/_/mongo

A named volume is persistent storage, not a backup

A Docker volume protects data from ordinary container removal, but it does not replace backups, tested restoration procedures, or secure storage.

Verify Docker persistence
use mongodb_course_lab

db.dockerCheck.find();
💡 After reconnecting to a newly created container that uses the same persistent volume, this query should return the previously inserted document. If the volume was removed, or the new container uses a different empty volume, the document will not be present.
Key Takeaways
  • Docker can run MongoDB in a reproducible container.
  • A named volume stores database files independently of the container.
  • Removing a container does not ordinarily remove its named volume.
  • Removing a volume deletes the data stored in it.
  • Local development credentials and configurations should not be copied into production.
Knowledge Check

You remove a MongoDB container but keep its named data volume. What should happen when a new compatible container is started using the same volume?

MongoDB Connection Strings in Depth

A MongoDB connection string tells the client how to locate a database deployment and provides connection options. Connection strings are often called MongoDB URIs.

Two commonly encountered formats are the standard connection string and the DNS seed-list connection string.

Standard connection string

mongodb://127.0.0.1:27017/learning

This URI specifies a local server, the default port, and learning as the database path.

SRV connection string

mongodb+srv://<username>:<password>@<cluster-host>/learning

The SRV format uses DNS seed-list discovery. It is commonly supplied by managed MongoDB deployments.

Common connection-string components

  • Scheme: mongodb:// or mongodb+srv://.
  • Host: The server address or DNS seed-list hostname.
  • Port: Optional in the URI, depending on the connection format.
  • Database path: The database name associated with the URI.
  • Credentials: Optional username and password information.
  • Query parameters: Additional connection and authentication options.

Authentication source

The database in which a user is authenticated may differ from the database that the application accesses.

For example:

mongodb://courseadmin:<password>@127.0.0.1:27017/learning?authSource=admin

Here, learning is the database in the URI path, while authSource=admin specifies the authentication database.

Special characters in credentials

Characters such as @, :, /, ?, and # have special meanings in URIs. Credentials containing reserved characters must be percent-encoded correctly.

Do not encode the entire connection string as though it were one credential. Encode the relevant username or password components when constructing the URI.

Read and write options

Connection strings can include options related to retryable writes, TLS, authentication, read preference, and write concern. The correct options depend on the deployment and application requirements.

For example, retryWrites=true requests retryable-write behavior when supported. It is not a universal guarantee that every failed operation will be retried successfully.

A write-concern option such as w=majority requests acknowledgment from a majority of voting data-bearing members under the applicable deployment semantics. It affects durability and latency trade-offs and should be understood before changing production settings.

Never expose a connection string in browser code

A database URI containing credentials is a server-side secret. In Next.js, keep it in a server-only environment variable such as MONGODB_URI, and do not prefix it with NEXT_PUBLIC_.

A browser should call an appropriately authenticated backend API rather than connecting directly to a private application database using privileged credentials.

Connection-string components
mongodb://: Standard connection scheme
Commonly used for direct host-and-port connections and standard MongoDB connection configurations.
mongodb+srv://: DNS seed-list scheme
Uses DNS SRV records to discover the deployment's server addresses.
authSource: Authentication database
Specifies the database used to authenticate the provided credentials.
retryWrites: Retryable-write option
Requests retryable writes when the deployment and operation support them.
Read a connection string from a server-side environment variable
const uri = process.env.MONGODB_URI;

if (!uri) {
 throw new Error("MONGODB_URI is not configured");
}

console.log("MongoDB URI is configured:", Boolean(uri));
💡 This Node.js example verifies that the environment variable exists without printing the secret. Do not log the complete URI because it may contain credentials or other sensitive connection information.
Key Takeaways
  • A MongoDB URI identifies the deployment and may contain connection options.
  • The database path and authentication source can be different.
  • Reserved URI characters in credentials must be encoded correctly.
  • Connection options can affect security, consistency, and performance.
  • Database connection strings must remain server-side secrets.
Knowledge Check

In a connection string ending with `/learning?authSource=admin`, what does `authSource=admin` specify?

Creating Databases and Collections Correctly

MongoDB's shell makes it easy to select a database and create collections, but database selection and physical creation are not the same operation.

Selecting a database

use learning

This changes the current database context in mongosh. It does not necessarily create a database immediately.

Creating a collection implicitly

A collection can be created when the first document is inserted:

db.courses.insertOne({
 title: "MongoDB Fundamentals",
 level: "beginner"
});

If courses does not exist, MongoDB ordinarily creates it as part of the insert operation.

Creating a collection explicitly

db.createCollection("students");

Explicit creation is useful when you want to configure collection options, validation, or other supported properties before inserting data.

Listing collections

db.getCollectionNames();

The shell returns collection names visible in the current database.

Inspecting collection information

db.getCollectionInfos();

This provides collection metadata available to the connected user.

Naming conventions

Prefer clear, consistent collection names that reflect the records or workload they contain.

Examples include:

  • users
  • courses
  • enrollments
  • orders
  • auditEvents

Naming conventions are not a substitute for data modeling. For example, creating an enrollments collection does not by itself establish referential integrity with a users collection.

Collection validation at creation time

You can combine collection creation with validation:

db.createCollection("students", {
 validator: {
 $jsonSchema: {
 bsonType: "object",
 required: ["name", "email"],
 properties: {
 name: { bsonType: "string" },
 email: { bsonType: "string" },
 age: { bsonType: "int", minimum: 0 }
 }
 }
 },
 validationAction: "error"
});

This example requires name and email to be strings. If age is present, it must be a BSON 32-bit integer greater than or equal to zero. Values represented using other numeric BSON types would not satisfy this specific bsonType rule.

If the collection already exists, the creation command will not simply replace its configuration. Use the appropriate collection-modification command when you need to update existing options.

Create and inspect a practice collection
use mongodb_course_lab

db.createCollection("practiceStudents");

db.practiceStudents.insertMany([
 { name: "Arun", age: 22 },
 { name: "Meera", age: 24 }
]);

printjson(db.getCollectionNames());
printjson(db.getCollectionInfos());
💡 The example explicitly creates a collection, inserts two documents, and inspects collection names and metadata. The collection will remain in the selected database after the shell session ends because the database persists its stored data.
Key Takeaways
  • The use command selects a database context.
  • A database is not necessarily created just because it has been selected.
  • Collections can be created implicitly or explicitly.
  • Explicit collection creation is useful when configuring validation and collection options.
  • Collection names and database structures should follow clear conventions.
Knowledge Check

What does `use learning` do in mongosh?

Environment Variables and Application Configuration

Applications should not hardcode database connection strings throughout their source code. Environment-based configuration makes it easier to separate development, testing, staging, and production settings.

Example project structure

my-node-app/
 src/
 db.js
 server.js
 .env
 .gitignore
 package.json

The exact structure depends on the application. The important principle is that sensitive configuration is managed outside committed application source code.

Example environment file

MONGODB_URI=mongodb://127.0.0.1:27017/learning
NODE_ENV=development

This example assumes a local development server without authentication. For an authenticated deployment, use an appropriate connection string and store the credentials securely.

Prevent secrets from entering source control

Add the environment file to .gitignore:

.env
.env.local
.env.*.local

If a secret was already committed, adding the file to .gitignore does not remove it from Git history or invalidate the exposed credential. Rotate the credential and follow the repository's secret-remediation process.

Loading variables in Node.js

Modern Node.js versions support loading environment files through built-in command-line options. For projects using a dotenv package, configuration can be loaded explicitly.

For example, install dotenv if your project uses that approach:

npm install dotenv

Then load the configuration before accessing the environment variable:

import dotenv from "dotenv";

dotenv.config();

const uri = process.env.MONGODB_URI;

if (!uri) {
 throw new Error("MONGODB_URI is missing");
}

Alternatively, configure your runtime or hosting platform to supply environment variables directly. Avoid loading the same environment file unnecessarily in many modules.

Next.js considerations

For a Next.js application, database access should occur in server-side code. Keep the MongoDB URI in a server-only variable such as MONGODB_URI.

Do not use NEXT_PUBLIC_MONGODB_URI. Variables with the NEXT_PUBLIC_ prefix are intended for values that can be exposed to browser-side code.

In the Pages Router, database operations may be performed in API routes or other server-side code. In the App Router, they may be performed in appropriate server-side route handlers or server components, depending on the architecture.

Production configuration

Production applications should obtain secrets from an appropriate secret manager or the hosting platform's protected environment configuration. Limit access to the credentials, rotate them when necessary, and avoid printing connection strings in logs.

Environment variables help organize configuration; they do not automatically encrypt every value or prevent access by processes that have permission to read them.

Never expose a database secret to the browser

A MongoDB connection URI may grant direct database access. Keep it on the server, restrict database privileges, and never return it in an API response or include it in browser bundles.

Validate database configuration safely
const mongodbUri = process.env.MONGODB_URI;

if (typeof mongodbUri !== "string" || mongodbUri.length === 0) {
 throw new Error("Missing required environment variable: MONGODB_URI");
}

export const databaseConfig = {
 uri: mongodbUri
};
💡 The module validates the required environment variable and exports a configuration object. It does not log the URI. In a real application, keep this module server-only and ensure the runtime has loaded or supplied the environment variable before importing it.
Key Takeaways
  • Environment variables separate configuration from source code.
  • A .gitignore entry prevents ordinary future tracking but does not erase previously committed secrets.
  • Node.js can read environment variables through process.env.
  • Next.js database operations should use server-side code.
  • Environment variables are not a replacement for access control and secret management.
Knowledge Check

Why should a MongoDB connection string containing credentials not use the `NEXT_PUBLIC_` prefix in Next.js?

Troubleshooting MongoDB Connection Errors

Connection problems are common when setting up a database. Learn to distinguish network failures, authentication failures, authorization failures, DNS problems, and server startup errors instead of treating every failure as the same issue.

1. Connection refused

A connection-refused error often indicates that no server is accepting connections at the specified address and port, although networking configuration can also affect the result.

Check:

  • Whether mongod is running.
  • Whether the configured port is correct.
  • Whether the server is listening on the expected interface.
  • Whether a firewall or container configuration is interfering.

2. Server selection timeout

A server selection timeout means the MongoDB driver could not select a suitable server within the configured timeout.

Possible causes include:

  • An unreachable deployment.
  • Incorrect hostname or SRV configuration.
  • A blocked network connection.
  • Atlas network access restrictions.
  • DNS resolution problems.
  • TLS or server topology configuration problems.

The timeout is the observed failure, not necessarily the root cause.

3. Authentication failure

An authentication error means the server did not accept the supplied authentication credentials or authentication configuration.

Check the username, password, authentication mechanism, authentication source, and URI encoding. Confirm that you are using the database user's credentials rather than your Atlas website login.

4. Authorization failure

Authentication and authorization are different. A user may connect successfully but lack permission to perform an insert, create an index, or execute an administrative command.

Check the user's roles and the database on which those privileges are granted.

5. DNS resolution failure

An SRV connection string depends on DNS SRV resolution. If the hostname is wrong or the environment cannot resolve the required records, the client may fail before connecting to the database server.

Check the hostname supplied by the deployment, DNS resolution, and any corporate network restrictions.

6. TLS or certificate errors

Managed deployments often require encrypted connections. Certificate validation failures can arise from an incorrect system clock, missing trusted certificate authorities, or TLS configuration problems.

Do not solve a production certificate error by disabling certificate validation. Fix the underlying trust or configuration problem.

7. MongoDB server is unavailable

If a local server fails to start, inspect the service status and logs. Check whether the data directory exists, whether the process can access it, and whether another process is already using the port.

Troubleshooting workflow

  1. Read the complete error message.
  2. Determine whether the failure occurs during DNS lookup, TCP connection, TLS negotiation, authentication, or command execution.
  3. Verify the hostname and port.
  4. Check server status or managed deployment status.
  5. Verify network access rules.
  6. Check credentials and authentication settings.
  7. Check authorization separately.
  8. Review logs without exposing secrets.
  9. Retry after correcting the actual cause.

Avoid repeatedly increasing timeouts without investigating the underlying issue. A longer timeout can delay failure without making an unreachable deployment available.

Diagnose by symptom
Connection refused: Check server and port
The target endpoint is not accepting the connection or a network component is rejecting it.
Server selection timeout: Check topology and connectivity
The driver could not select an appropriate server before its deadline.
Authentication failed: Check credentials and authSource
The server did not accept the supplied authentication configuration.
Not authorized: Check user roles
The connection may be valid, but the attempted operation is not permitted.
DNS or SRV error: Check hostname and DNS
The connection target could not be resolved correctly.
Do not disable security to fix connectivity

Avoid disabling TLS verification, opening every network address permanently, or granting unrestricted database privileges just to make a connection succeed.

Run a basic connectivity check
try {
 const result = await db.command({ ping: 1 });
 console.log("MongoDB responded:", result.ok === 1);
} catch (error) {
 console.error("MongoDB connectivity check failed:", {
 name: error.name,
 message: error.message
 });
}
💡 This snippet assumes db is an initialized MongoDB Node.js driver Db object and runs inside an async function or supported top-level-await context. It logs the error name and message without printing connection credentials. A failed ping should be investigated using the specific error and surrounding connection configuration.
Key Takeaways
  • Connection errors have different causes and require different diagnostics.
  • Server selection timeouts are symptoms, not definitive diagnoses.
  • Authentication verifies identity, while authorization controls permitted operations.
  • DNS, networking, TLS, server state, and credentials can all affect connectivity.
  • Never expose passwords or disable important security controls while troubleshooting.
Knowledge Check

A MongoDB application connects successfully, but inserts fail with an authorization error. What should you investigate first?

Practical Lab: Create a Repeatable MongoDB Environment

In this lab, create a database, configure a collection, insert documents, and verify that the environment works. You can use Atlas, a local MongoDB server, or Docker.

Step 1: Connect to MongoDB

Connect using mongosh and verify the connection:

db.runCommand({ ping: 1 });

Step 2: Select a dedicated practice database

use mongodb_environment_lab

Step 3: Create a collection with validation

db.createCollection("developers", {
 validator: {
 $jsonSchema: {
 bsonType: "object",
 required: ["name", "email", "experienceYears"],
 properties: {
 name: {
 bsonType: "string",
 minLength: 1
 },
 email: {
 bsonType: "string",
 minLength: 3
 },
 experienceYears: {
 bsonType: ["int", "long", "double", "decimal"],
 minimum: 0
 },
 skills: {
 bsonType: "array",
 items: {
 bsonType: "string"
 }
 },
 location: {
 bsonType: "object",
 properties: {
 city: { bsonType: "string" },
 country: { bsonType: "string" }
 }
 }
 }
 }
 },
 validationLevel: "strict",
 validationAction: "error"
});

Step 4: Insert valid documents

db.developers.insertMany([
 {
 name: "Arun",
 email: "arun@example.com",
 experienceYears: 3,
 skills: ["JavaScript", "Node.js", "MongoDB"],
 location: {
 city: "Chennai",
 country: "India"
 }
 },
 {
 name: "Meera",
 email: "meera@example.com",
 experienceYears: 5,
 skills: ["React", "TypeScript", "MongoDB"],
 location: {
 city: "Bengaluru",
 country: "India"
 }
 }
]);

Step 5: Read and inspect documents

db.developers.find();

db.getCollectionNames();

db.getCollectionInfos();

Step 6: Test validation

Attempt to insert a document missing email:

db.developers.insertOne({
 name: "Invalid Example",
 experienceYears: 2
});

The operation should fail because email is required. Run this only as an intentional validation test in your practice environment.

Step 7: Verify nested data

db.developers.find({ "location.city": "Chennai" });

This query uses dot notation to find developers whose nested city field is Chennai.

Step 8: Count documents

db.developers.countDocuments({});

If both valid documents were inserted successfully and no additional documents were added, the result should be 2.

Step 9: Check environment configuration

If you are using a Node.js application, confirm that the connection string is supplied through the server-side MONGODB_URI environment variable. Verify its presence without printing its value.

Step 10: Clean up if needed

Only if you want to remove this disposable practice collection:

db.developers.drop();

Dropping the collection removes its documents and collection configuration. Do not execute this command against a production collection.

Lab challenges

  1. Create another collection called courses.
  2. Insert three course documents with different difficulty levels.
  3. Find courses with a particular difficulty.
  4. Create a validator that requires title and level.
  5. Intentionally attempt an invalid insert and explain the error.
  6. Explain why a successful ping does not guarantee write permission.
  7. Describe how you would prevent a database URI from reaching browser code.
  8. Explain how a Docker named volume differs from a container.
  9. Identify the first three things you would check after a server selection timeout.
  10. Explain why a development database should be separate from production.
Verify the practice environment
db.runCommand({ ping: 1 });

print("Database:", db.getName());
print("Collections:");
printjson(db.getCollectionNames());

print("Developer count:", db.developers.countDocuments({}));

print("Chennai developers:");
printjson(
 db.developers.find({ "location.city": "Chennai" }).toArray()
);
💡 The lab verification checks deployment responsiveness, the selected database, visible collections, document count, and a nested-field query. If a command fails, inspect the actual error and the connected user's privileges rather than assuming the entire deployment is unavailable.
Key Takeaways
  • A working environment requires connectivity, correct authentication, and appropriate permissions.
  • Collection validation can enforce required fields and acceptable BSON types.
  • Database and collection metadata can be inspected using mongosh.
  • Nested documents can be queried using dot notation.
  • Practice destructive operations only in disposable development environments.
Knowledge Check

In the lab, why does the invalid developer insert fail?

Chapter Review and Readiness Check

You have now learned how to select a MongoDB environment, establish a connection, configure a development database, and investigate common setup failures.

Before continuing, make sure you can explain these concepts:

  • The differences between Atlas, Community Server, and Docker.
  • The roles of mongod and mongosh.
  • How to verify connectivity with a ping command.
  • How standard and SRV connection strings differ.
  • Why authSource can differ from the database in the connection-string path.
  • Why a successful connection does not guarantee write permission.
  • How to select a database and create a collection.
  • How collection validation enforces required fields and types.
  • How environment variables keep configuration separate from source code.
  • Why database credentials must not be exposed to browser-side code.
  • How to distinguish connection-refused, server-selection, authentication, and authorization errors.
  • Why persistent storage is not a replacement for backups.

Final readiness exercise

Create a working practice database and collection. Insert at least three documents, verify the data, intentionally test a validation failure, and document the steps required to reconnect after restarting your local server or container.

If using Atlas, record the connection procedure without recording or publishing the actual password.

Next chapter

The next chapter will introduce MongoDB data types and BSON in greater depth. It will cover ObjectId, strings, numeric types, Boolean values, null, missing fields, arrays, embedded documents, dates, timestamps, Decimal128, binary values, and the practical consequences of choosing the wrong type.

Key Takeaways
  • Reliable database setup involves more than installing the server.
  • Connection configuration, authentication, authorization, and network access are distinct concerns.
  • MongoDB supports explicit collection validation.
  • Server-side secret management is essential for application security.
  • Troubleshooting should begin by identifying the stage at which a connection or operation fails.
Knowledge Check

Which statement correctly describes MongoDB connection troubleshooting?