Tools: How To Use the MongoDB Shell
Source: DigitalOcean
By Mateusz Papiernik, Mark Drake and Manikandan Kurup The MongoDB Shell, called mongosh, is the officially supported command-line interface for working with MongoDB. It allows you to connect to a MongoDB server, run queries, insert and update documents, manage indexes, and execute JavaScript directly against your database. If you are running MongoDB locally or using MongoDB Atlas in the cloud, mongosh provides a consistent way to interact with your data. It replaces the legacy mongo shell and introduces a modern, improved experience built on Node.js. In this guide, you will learn how to connect to local, remote, and MongoDB Atlas deployments, navigate and explore databases using the shell, perform CRUD operations with modern helper methods, use query operators and projections effectively, sort and paginate results, create and manage indexes, execute JavaScript directly inside the shell, and troubleshoot common connection and authorization issues that arise in real-world environments. By the end of this article, you will be comfortable working with mongosh in development and administrative workflows. To follow this tutorial, you will need: mongosh is the official MongoDB Shell introduced by MongoDB to replace the legacy mongo shell. It is built on Node.js, which enables a more modern interactive experience in the terminal. In practice, this includes clearer error messages, improved syntax highlighting, and autocomplete that helps you discover commands and reduce typos as you work. mongosh also formats results in a more readable way than the legacy shell, and it supports running JavaScript directly in your session so you can script quick checks and administrative tasks without leaving the CLI. Because it runs on a modern runtime, mongosh also supports features that make day-to-day administration easier. For example, it provides richer output for many commands, helpful inline documentation through shell help methods, and more consistent behavior when working with Extended JSON (EJSON) data types such as ObjectId() and ISODate(). It is also designed to work cleanly with modern connection strings, including authenticated connections and TLS-enabled deployments. Unlike the older mongo shell, mongosh is actively maintained and recommended for new MongoDB deployments. You can use it with local MongoDB Community Edition or MongoDB Enterprise Advanced, connect to self-hosted remote MongoDB servers, and administer MongoDB Atlas clusters in the cloud while keeping the same core workflow across environments. In addition to interactive use, mongosh supports automation-friendly patterns such as running commands non-interactively (for example, by using --eval for one-off expressions or --file to execute a JavaScript script), which is useful for repeatable checks and operational runbooks. At a practical level, the biggest differences between mongo and mongosh are that mongosh is the supported replacement (the legacy mongo shell is deprecated), it runs on a Node.js runtime (so modern JavaScript syntax works well), and it provides a more discoverable interactive experience with richer help and autocomplete. Let’s look at the most common ways to connect with mongosh, including local connections, authenticated connections, remote hosts, and MongoDB Atlas clusters. If MongoDB is installed and running locally on the default port 27017, you can connect by simply running: When you run mongosh with no arguments, it attempts to connect to a local server on port 27017 (typically over the loopback interface). In many environments, this default resolves to a connection string like: If your MongoDB service is bound to a different interface or port, you can be explicit: After connecting successfully, you will see a welcome message that includes: The prompt typically looks like this: This indicates that your current database context is test. This is simply the database you are currently using in the shell; no database is created until you write data (for example, by inserting a document into a collection). If you want to start in a specific database immediately, you can include it in the URI: If authentication is enabled, you must provide credentials. MongoDB users are defined in a specific authentication database (often admin), which is not always the same database you want to work in. Use the following flags to provide your username and authentication database, and then enter your password when mongosh prompts you. You will be prompted for the password. Tip: Avoid putting passwords directly in your shell history. Let mongosh prompt for the password, or use your organization’s preferred secret management mechanism. The connection string format is the recommended modern approach: This explicitly defines: Using a full connection string improves clarity and is required for many production environments. If your user is stored in a different authentication database than the database you want to use, you can specify it with authSource: In secured deployments, you may also need to specify TLS options (for example, when your server requires encrypted connections). The exact flags and certificates depend on how the server is configured. To connect to a remote server: In most real-world environments, authentication and TLS are enabled. A connection string is often clearer because it keeps all connection settings in one place: If you are connecting to a single host that is not part of a replica set (or you need to force a direct connection for troubleshooting), you may need directConnection=true in the URI. Conversely, if you are connecting to a replica set, your URI may include multiple hosts and a replicaSet name. When using MongoDB Atlas, you typically connect using an SRV connection string provided in the Atlas dashboard: For example, if you want to connect to a specific database and include common Atlas options, you can use a connection string like this: Atlas uses the SRV format to provide a seed list of hosts via DNS, and it requires TLS by default. Many SRV URIs also include options like write concern and retryable writes (Atlas provides a copy/paste string you can use as-is). If your password contains special characters, make sure it is URL-encoded in the URI. To avoid placing the password in the command, you can also supply the username and let mongosh prompt for the password: In this section, we cover the core commands you will use to understand your current context, switch databases, list collections, and discover available methods while working interactively in mongosh. The mongosh prompt shows the current database: If you switch databases, the prompt updates automatically. In addition to being a database client, mongosh is a JavaScript-based interactive environment. It supports: To display the current database: If you want the name as a string (useful in scripts), you can also use: Run the following command to switch the active database for the current session. MongoDB creates databases lazily, which means the database is created only after the first write that creates a collection. Best practice: In production systems, avoid accidental database creation by using controlled deployment scripts. If you want to reference another database without changing the interactive context, you can use db.getSiblingDB("<database>") in scripts. Run the following command to list the databases: Note that show dbs requires privileges that include listing databases. If you do not have permission, MongoDB may return an authorization error. To list collections in the current database, run: You can also list collections programmatically using: mongosh includes built-in help that you can use to explore available commands and methods without leaving the shell. To view general, shell-level help, run: To see database-related methods and usage examples, run: To view methods that are available on a collection object (for example, CRUD helpers and index methods), run: These commands print method names and short descriptions so you can quickly confirm the correct syntax for a task. Autocomplete in mongosh helps you type faster and avoid common syntax mistakes. Press Tab to complete or suggest database names, collection names, method names, and operators based on what you have typed so far. If there are multiple possible completions, mongosh will show a list of candidates so you can select the one you want. MongoDB exposes create, read, update, and delete (CRUD) operations through explicit methods on a collection. In mongosh, you typically run these methods as db.<collection>.<method>(...), where <collection> is the collection name. Modern MongoDB versions encourage using explicit helpers such as insertOne(), find(), updateOne(), and deleteMany() because they have consistent behavior and return structured result objects. Safety Notes for Production: In production environments, treat shell access as powerful administrative access and keep it tightly controlled. Double-check the server and database you are connected to before running write operations, prefer least-privilege users, and validate potentially expensive queries (for example, collection scans or large sorts) in staging first when possible. For destructive operations, confirm your filter with a find() query, and consider using limit() while you verify your workflow. You use insert operations to create new documents in a collection. In most workflows, insertOne() is used for single documents and insertMany() is used for batch inserts, and MongoDB will generate an _id value automatically if you do not provide one. Use the following example to insert a single document into a collection. This inserts a single document into the apples collection. If you do not provide an _id field, MongoDB automatically generates a unique _id (usually an ObjectId) and stores it with the document. The method returns an InsertOneResult object that includes the generated insertedId so you can reference the document later. Use the following example to insert multiple documents in a single operation. This inserts multiple documents in a single call and returns an InsertManyResult that includes an array of inserted IDs. By default, insertMany() is ordered, which means it stops at the first error (for example, a duplicate _id) unless you explicitly change this behavior. To read documents, you typically use find() to return a cursor (a pointer to a result set) and then iterate through or print the results. To retrieve all documents in a collection, run: To retrieve a single document, use findOne(), which returns the first matching document (or null if none match): When exploring data interactively, formatted output can be easier to read. In mongosh, output is already formatted for readability, but you can still use .pretty() if you prefer expanded formatting. In real queries, you will usually pass a filter document and optionally a projection document. For example, db.apples.find({ price: { $gte: 3 } }, { name: 1, price: 1, _id: 0 }) returns only name and price for apples priced at 3 or higher. Updates modify documents that match a filter. In most cases you should use update operators like $set so you change only the fields you intend to change. To update a single matching document, use updateOne(): This operation returns an UpdateResult that includes fields such as matchedCount and modifiedCount, which help you confirm what happened. To update every document that matches your filter, use updateMany(): If you want MongoDB to insert a document when no matching document is found, you can use the upsert option (for example, db.apples.updateOne({ name: "Gala" }, { $set: { price: 3 } }, { upsert: true })). Delete operations permanently remove documents that match your filter, so it is a good habit to run the equivalent find() first to confirm what will be affected. To delete a single matching document, use deleteOne(): To delete all matching documents, use deleteMany(): Note: The old insert() helper is deprecated. Use insertOne() or insertMany() so you get consistent behavior and a structured result object. MongoDB’s aggregation framework is accessed through the aggregate() command. In mongosh, you run aggregations as db.<collection>.aggregate(...), typically passing an array of stages (such as $match, $group, and $sort) that describes how MongoDB should transform and summarize the data. Compared to a basic find(), aggregate() is useful when you need to compute derived values, reshape documents, join related data, or calculate summaries (for example, totals, counts, and averages). The result of aggregate() is a cursor, which means MongoDB can stream results; in interactive work you can print the cursor output directly, or convert it to an array with .toArray() when you want to capture and reuse the results. To keep aggregations readable and easier to debug, build the pipeline one stage at a time. It is common to start with a selective $match to reduce the amount of data processed, add projection or computed fields, and then group or sort. The stages below are some of the most frequently used building blocks when writing aggregation commands in mongosh. To preview a few documents for a region and compute a derived revenue value, you can combine $match and $project like this: To count how many sales documents exist per region, use $group with $sum: 1: If your documents contain arrays, $unwind is a common way to count individual elements. For example, the commands below create a small orders dataset and then count how often each item appears: In production environments, start aggregations with a selective $match where possible and ensure the fields you filter and sort on are indexed, because running aggregate() on large collections can be expensive. When you are troubleshooting slow aggregations, consider checking the query plan with explain() and adding a small $limit early while validating the shape of the results. To see how MongoDB plans to execute an aggregation, you can run an explained version like this: MongoDB queries are expressed as JSON-like documents, and many advanced query features are enabled through operators that begin with $. You use these operators inside a filter document passed to methods like find(), findOne(), updateOne(), and deleteMany() to express comparisons, boolean logic, membership tests, and pattern matching. This query matches documents where the price field exists and is greater than 2. If you need to match multiple conditions on different fields, you can include them in the same filter document (MongoDB treats top-level field conditions as an implicit AND). MongoDB provides logical operators for combining conditions when you need explicit boolean logic: Element and evaluation operators help you match on field existence, membership, and patterns: Projection controls which fields are returned in the query result. You specify projection as the second argument to find() or findOne(), using 1 to include a field and 0 to exclude a field. This projection includes name and excludes _id, which is a common pattern when you want to hide the internal identifier in output. As a general rule, avoid mixing inclusion and exclusion in the same projection document (except for _id), because MongoDB treats them differently depending on the projection style. MongoDB cursors can be sorted and paginated to control how results are returned. In mongosh, you typically apply sort(), limit(), and skip() to a find() cursor to build predictable result pages while exploring data. Use the following example to sort documents returned by a query. Use 1 for ascending order and -1 for descending order. If you sort on multiple fields, MongoDB applies them left to right (for example, { category: 1, price: -1 } sorts by category first and then by price within each category). For best performance, sort on fields that are covered by an index. Use the following example to limit the number of returned documents. limit() is useful for sampling data and for building paginated UIs where you want a fixed page size. Use the following example to skip documents for pagination. For large datasets, consider range-based pagination using an indexed field (for example, filtering on _id or a timestamp) instead of skip(), because skip() still requires MongoDB to walk past the skipped documents. A common pattern is to sort by an indexed field and then filter on a value greater than the last seen value to fetch the next page efficiently. Indexes are data structures that help MongoDB locate documents more efficiently for common filters and sorts. In this section, we show you how to create, inspect, and remove indexes, and highlight the main tradeoffs you should consider in production. Indexes improve query performance by allowing MongoDB to locate matching documents without scanning the entire collection. Without an appropriate index, MongoDB often falls back to a collection scan, which becomes slower as your dataset grows. Create indexes when your workload includes any of the following: Indexes can also enforce constraints when configured appropriately, such as unique indexes that prevent duplicate values. Use the following command to create an index on a field. This creates a single-field ascending index on name. If your queries commonly filter on multiple fields, consider compound indexes (for example, { category: 1, price: 1 }). You can also create specialized indexes such as text indexes for full-text search, TTL indexes for time-based expiration, and unique indexes for enforcing uniqueness. Use the following command to list a collection’s indexes. This returns index definitions, including the index name, key pattern, and options. Use the following command to remove an existing index by name. Dropping an index removes it from the collection and can affect query performance immediately, so it is best to verify usage before removing indexes in production. Because mongosh is JavaScript-based, you can write small scripts to automate repetitive tasks, perform quick checks, and load reusable helpers. Let’s see a few practical patterns you can use safely in interactive sessions. For example, you can assign the result of a MongoDB operation to a variable like this. Because mongosh supports JavaScript, you can store values in variables, reuse them across commands, and build small scripts to automate repetitive tasks. You can also run multi-line JavaScript blocks such as loops. Use load() to execute a JavaScript file in the current shell session. Loading a script is helpful for repeatable tasks such as creating indexes, running a set of sanity-check queries, or preparing demo data. In automation contexts, you can also run scripts directly using the mongosh --file flag. You can run a one-off command without entering an interactive shell by using --eval, which is useful for quick health checks in CI/CD or operational runbooks. For longer workflows, put commands in a .js file and run it with --file so it is easier to review, version, and re-run. mongosh runs on a Node.js runtime, which means you can use modern JavaScript syntax and control flow for interactive work and scripting. However, it is not a general-purpose application runtime, and business logic should typically live in your application codebase or dedicated services rather than in ad-hoc shell scripts. The errors below are some of the most common issues you will run into when connecting to MongoDB and running commands in mongosh. Use the guidance in each subsection to quickly determine whether the root cause is credentials, permissions, network access, or local installation. An authentication failure usually indicates incorrect credentials, an incorrect authentication database, or a mismatch between how the server expects you to authenticate and how you are connecting. Start by verifying the username and password, and then confirm which database the user is defined in. Many deployments create users in the admin database, but users can also be created in an application database. If you are authenticating with flags, make sure you specify the correct authentication database: If you are using a connection string, set the authentication database with authSource when it differs from the database you want to use: Also confirm that you are connecting to the intended server and environment (for example, staging vs production), because the same username may exist in multiple places with different passwords or roles. In secured environments, authentication failures can also appear if TLS is required but not configured, because the server may terminate the connection during negotiation. A “connection refused” error typically means there is no service listening at the host and port you specified, or the connection is being blocked before it reaches MongoDB. First, verify that the MongoDB service is running and listening on the expected port (27017 is the default). Next, confirm that you are using the correct hostname or IP address. If you are connecting locally, double-check that MongoDB is bound to the loopback interface (127.0.0.1) and not a different interface. If you are connecting remotely, verify that: If the connection is not refused but instead times out, that often indicates network path or firewall issues. If you see TLS-related messages, ensure you are using the correct scheme and options (for example, Atlas uses mongodb+srv:// and requires TLS). If your system reports that mongosh is not found, the shell is either not installed or it is not available on your PATH. Start by checking whether mongosh is installed and discoverable: If that command fails, install the MongoDB Shell from official MongoDB sources for your platform. After installation, make sure your PATH includes the directory that contains the mongosh binary so the command can be executed from any directory. If you installed mongosh but it still is not found, open a new terminal session (some shells load updated PATH values only on startup) and recheck. On macOS and Linux, you can also use which mongosh to see whether the command resolves to an executable. Authorization errors occur when your authenticated user does not have the required roles to perform an operation. This is different from authentication: you have successfully logged in, but MongoDB is denying the specific action you tried to perform (for example, running show dbs, creating an index, or writing to a collection). When you see an authorization error, identify the exact command that failed and the database it targets, and then verify the user’s roles. For application access, a common minimal role is readWrite on a specific database. Administrative operations such as user management, server configuration, or listing all databases typically require broader permissions, so assign them sparingly and prefer least-privilege role sets. If you are connected to the correct server but the command still fails, confirm that you authenticated as the intended user (for example, by checking the connection string and authentication database) and that you are operating in the expected database context. For example, the following deprecated helper may trigger a warning: To fix the warning, replace it with the modern equivalent: When you see deprecation warnings, update scripts and runbooks to use the modern helper methods so you get predictable return values and forward-compatible behavior. Deprecation warnings are especially important in automation, because older helpers may behave differently across versions or may be removed in future releases. Updating to methods like insertOne(), insertMany(), updateOne(), and deleteMany() also makes it easier to handle errors programmatically, because these helpers return consistent, structured result objects. mongosh is the modern, officially supported MongoDB Shell, and it is implemented on top of a Node.js runtime. Compared to the legacy mongo shell, mongosh provides a more up-to-date interactive experience (for example, improved error messages, better output formatting, and richer help and autocomplete) and is designed to work cleanly with modern connection string formats and secured deployments. The mongo shell is the older, legacy shell and is deprecated. In practice, that means you should use mongosh for new scripts, documentation, and operational workflows, and you should plan to migrate any existing mongo-based runbooks to mongosh where possible. No. You can manage and query Atlas in multiple ways, depending on what you are trying to do. For interactive administration and troubleshooting, many teams use mongosh because it provides direct CLI access to the cluster using standard MongoDB commands. You can also use the Atlas UI for many administrative tasks, and application code typically connects through official MongoDB drivers. Even when you do not use mongosh day-to-day, it is still useful to have available for operational tasks such as verifying indexes, testing queries quickly, checking user permissions, or validating connectivity from a given network. Yes, but it is best used for administrative tasks, debugging, and maintenance rather than as part of an application’s normal request flow. For example, using mongosh to inspect an index, confirm a document shape, or run a targeted fix can be appropriate. In production environments, be careful with any command that can scan a large collection, modify many documents, or drop indexes, because it can impact performance and availability. Prefer least-privilege users, run changes during planned maintenance windows when appropriate, and validate commands on a staging environment first. Use the SRV connection string provided in the Atlas dashboard: Atlas SRV connection strings use DNS to provide the host list, and Atlas requires TLS by default. In Atlas, make sure your client’s IP address is allowlisted (Network Access), and use a database user created in the Atlas Database Access settings. If your password contains special characters, URL-encode it, or omit it from the URI and let mongosh prompt you. Yes. mongosh runs on a Node.js runtime, so you can use modern JavaScript syntax for control flow and small scripts (for example, variables, loops, and helper functions) directly in the shell. This is useful for repeatable operational tasks such as generating test data, running a sequence of checks, or formatting output. However, the shell is best used for administration and debugging. Application business logic should generally remain in your application codebase and use an official MongoDB driver. To list all databases, run: This displays all databases available on the connected server. If show dbs returns an authorization error, your user likely does not have permission to list databases. In that case, you can still work within databases you are authorized for, but you may need an administrator to grant the appropriate role if listing is required for your workflow. In this guide, you learned how to use mongosh to connect to local MongoDB servers, remote deployments, and MongoDB Atlas using modern connection strings and secure defaults. You also practiced the core workflows you will use most often in day-to-day work, including navigating databases and collections, running queries with operators and projections, and performing CRUD operations with the current helper methods. Along the way, you covered practical techniques like sorting and paginating results, creating and managing indexes, and using JavaScript in the shell for quick checks and repeatable tasks. With these fundamentals, you can confidently work with mongosh for development, troubleshooting, and routine administration using modern, supported commands and best practices. For more MongoDB-related tutorials, check out the following articles: Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases. Learn more about our products MongoDB is a document-oriented NoSQL database management system (DBMS). Unlike traditional relational DBMSs, which store data in tables consisting of rows and columns, MongoDB stores data in JSON-like structures referred to as documents. This series provides an overview of MongoDB’s features and how you can use them to manage and interact with your data. Browse Series: 16 tutorials Creating bespoke software ◦ CTO & co-founder at Makimo. I'm a software enginner & a geek. I like making impossible things possible. And I need tea. Former Technical Writer at DigitalOcean. Focused on SysAdmin topics including Debian 11, Ubuntu 22.04, Ubuntu 20.04, Databases, SQL and PostgreSQL. With over 6 years of experience in tech publishing, Mani has edited and published more than 75 books covering a wide range of data science topics. Known for his strong attention to detail and technical knowledge, Mani specializes in creating clear, concise, and easy-to-understand content tailored for developers. This textbox defaults to using Markdown to format your answer. You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link! Please complete your information! Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation. Full documentation for every DigitalOcean product. The Wave has everything you need to know about building a business, from raising funding to marketing your product. Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter. New accounts only. By submitting your email you agree to our Privacy Policy Scale up as you grow — whether you're running one virtual machine or ten thousand. Sign up and get $200 in credit for your first 60 days with DigitalOcean.* *This promotional offer applies to new accounts only.