MongoDB Developer
Sign in to follow topics
MongoDB Developer Centerchevron-right
Developer Topicschevron-right

Build an Inventory Management System Using MongoDB Atlas

Rami Pinto Prieto17 min read • Published Dec 05, 2023 • Updated Dec 05, 2023
Facebook Icontwitter iconlinkedin icon
Rate this tutorial
In the competitive retail landscape, having the right stock in the right place at the right time is crucial. Too little inventory when and where it’s needed can create unhappy customers. However, a large inventory can increase costs and risks associated with its storage. Companies of all sizes struggle with inventory management. Solutions such as a single view of inventory, real-time analytics, and event-driven architectures can help your businesses overcome these challenges and take your inventory management to the next level. By the end of this guide, you'll have an inventory management up and running capable of all the solutions mentioned above.
We will walk you through the process of configuring and using MongoDB Atlas as your back end for your Next.js app, a powerful framework for building modern web applications with React.
The architecture we're about to set up is depicted in the diagram below:
Inventory management system architecture using MongoDB Atlas and Next.js
This will result in a web app capable of efficiently navigating through your product catalog, receiving alerts, and automating restock workflows, all while maintaining control of your inventory through real-time analytics. Check out the end result here.
Let's get started!


Before you begin working with this React Next.js project, ensure that you have the following prerequisites set up in your development environment:
  • git (version 2.39 or higher): This project utilizes Git for version control. Make sure you have Git installed on your system. You can download and install the latest version of Git from the official website: Git Downloads.
  • npm (version 9.6 or higher): The project relies on npm (Node Package Manager) to manage dependencies and run scripts. You need to have npm installed on your machine. You can download Node.js from the official website: Node.js Downloads. After installing Node.js, npm will be available by default.
  • MongoDB Compass (version 1.40.4 or higher): Compass is a GUI for querying, aggregating, and analyzing your MongoDB data in a visual environment. Download and install the last version of MongoDB Compass.
  • MongoDB Atlas Cluster (M0 or higher): This project uses a MongoDB Atlas cluster to manage the database. You should have a MongoDB Atlas account and a minimum free tier cluster set up. If you don't have an account, you can sign up for free at MongoDB Atlas. Once you have an account, follow these steps to set up a minimum free tier cluster or follow the Getting Started guide:
    • Log in to your MongoDB Atlas account.
    • Create a new project or use an existing one, and then click "Create a new database."
    • Choose the free tier option (M0).
    • You can choose the cloud provider of your choice but we recommend using the same provider and region both for the cluster and the app hosting in order to improve performance.
    • Configure the cluster settings according to your preferences and then click "finish and close" on the bottom right.

MongoDB Atlas configuration

Set up a MongoDB Atlas cluster
To get started with MongoDB Atlas, follow these steps to set up your database:
  1. If it's your first time using MongoDB Atlas, you will need to create a cluster. Navigate to the Database Deployments page for your project, open the Build a Database dialog, select a cluster type and cluster tier, and click "Create Cluster." A shared M0 sandbox tier will be enough to follow this tutorial, but there will be some optional features only available to clusters M10 and above.
  2. Once the cluster is set up, click the "Connect" button and select the "Drivers" section. Choose the latest version of Node.js and copy the provided connection string. It should resemble something like this:
    Note: You will need the connection string to set up your environment variables later (MONGODB_URI).
  3. Proceed to the "Browse Collections" section in your MongoDB Atlas dashboard. If it's the first time creating a database in MongoDB, click "add my own data." Create a new database, choosing a database name that suits your application, such as "inventory_management." For the collection name, call it "products." Ignore additional preferences.
    Note: You will need the database name to set up your environment variables later (MONGODB_DATABASE_NAME).
  4. Inside the newly created database, add three collections:
    • products : This collection will store your product and stock data.
    • orders : This collection will track order details when orders are placed through the application.
    • sales : This collection will store information about sales transactions made. The application can simulate sales flows on demand. Products, orders and sales collections schemas
  5. For the initial setup, you can manually create products within the "products" collection. Ensure that you follow the defined data schema. If you prefer, you can load predefined products available. Copy the content of /data/product_sample.json if you want to load one document, or load the entire sample set by using the /data/products.json file. You can insert these documents into the product collection using tools such as MongoDB Atlas, MongoDB Compass, or mongoimport from MongoDB Database Tools.
Warning: If you are using MongoDB Atlas, keep in mind that you can only insert one document at a time. You can use MongoDB Compass and mongoimport to insert multiple documents at a time.
Let's see how you can upload the entire product sample set using MongoDB Compass.
  1. First, download the /data/products.json file.
  2. Open MongoDB Compass, paste your connection string into the "New Connection" menu, and click "Connect" or "Save & Connect."
  3. Navigate to the "products" collection in your database using the left-side menu, and select it.
  4. Your collection will be empty and it will show an "Import Data" button in the middle of the screen. Click it and select the products.json file you just downloaded. Confirm the import and you will see 17 documents in your "products" collection.
Set up Atlas App Services
To enable real-time capabilities for your Next.js application, follow these steps to set up Atlas App Services:
  1. Navigate to the "App Services" section in Atlas, which is located next to "Data Services" at the top of the page.
  2. Click on "Create a New App." Provide a name for your app and link it to the database you previously created. Confirm the creation of the app service.
  3. Once you're inside your application, make a note of the automatically generated App ID. It will have a format similar to:
    Note: You will need the App ID to set up your environment variables later (REALM_APP_ID).
  4. Give access to the two collections that we want to monitor in real-time: products, for low-stock alerts, and sales, for real-time analytics.
    1. In the sidebar menu under "Data access," navigate to "Rules." Locate your database, under the products collection, click "readAll," and then click "add preset role." Please, remember to click "review draft and deploy."
    2. After the access rule for the first collection has been deployed, repeat the same process for the sales collection.
  5. Proceed to the "Authentication" section. Enable the option to "Allow users to log in anonymously." This will provide a simple way for users to interact with your app without requiring explicit authentication. Again, remember to click "review draft and deploy."
Set up Atlas Search and filter facets
Navigating your product catalog efficiently is an important aspect of inventory management. You don't want to spend more time than necessary locating the product or set of products that need a stock level check. A modern reliable search experience and flexible filtering capabilities will make it easier for your workforce to find the right product whenever they need it. Using MongoDB Atlas, you can easily provide this functionality through search indexes.
Follow these steps to configure search indexes for full-text search and filter facets:
  1. Return to the "Data Services" section within Atlas. Select your cluster and click on "Search" located next to "Collections."
  2. If you are in the M0 tier, you can create two search indexes for the products collection. This will allow you to merely search across the products collection. However, if you have a tier above M0, you can create a total of six search indexes, two for each collection — one for search and another for filter facets.
  3. Let's begin with creating the indexes for full-text search:
    1. Click "Create Search Index."
    2. You can choose to use either the Visual or JSON editor. For the purposes of this tutorial, let's stick with the Visual Editor. Click "Next."
    3. Leave the index name as "default."
    4. Select your database and choose one of the three collections created (e.g., products).
    5. Keep the default Index Configurations unchanged and click "Create Index."
    6. After a few moments, your index will be ready for use. While you wait, you can proceed to create the other two search indexes for the "orders" and "sales" collections.
    Important: The name of the index must be the same in order for the application to be able to work properly.
  4. Now, let's proceed to create the indexes required for the filter facets. Note that this process is slightly different from creating default search indexes:
    1. Click "Create Index" again, select the Visual Editor, and click "Next."
    2. Name this index "facets."
    3. Select your database and one of the three collections for which you're creating these types of indexes. Click "Next."
    4. Choose "Refine Your Index" below the "Index Configurations" tab, deactivate "Dynamic Mapping," and add the Field Mappings as specified below for each collection:
      1. Products Collection:
        Field NameData Type
      2. Orders Collection:
        Field NameData Type
      3. Sales Collection:
        Field NameData Type
  5. Click save and then confirm "Create Search Index." The indexing process will take some time. You can create indexes for other collections while waiting for the indexing to complete.
Important: The name of the index must be the same in order for the application to be able to work properly.
When you are done setting up these search indexes and filter facets, your application will have gained powerful search and filtering capabilities, making it more user-friendly and efficient in managing inventory data.
Set up Atlas Charts
Enhance your application's visualization and analytics capabilities with Atlas Charts. Follow these steps to set up two dashboards — one for product information and another for general analytics:
  1. Navigate to the "Charts" section located next to "App Services."
  2. Let's begin by creating the product dashboard:
    • If this is your first time using Atlas Charts, click on "Chart builder." Then, select the relevant project, the database, and the collection.
    • If you've already used Atlas Charts (i.e., you're not a first-time user), then click on "Add Dashboard" in the top right corner. Give the dashboard a name and an optional description. Choose a name that clearly reflects the purpose of the dashboard. You don't need to worry about the charts in the dashboard for now. You'll configure them after the app is ready to use.
  3. Return to the Dashboards menu, click on the three dots in the top right corner of the newly created dashboard, and select "Embed."
  4. Check the "Enable unauthenticated access" option. In the "Allowed filter fields" section, edit the fields and select "Allow all fields in the data sources used in this dashboard." Choose the embedding method through the JavaScript SDK, and copy both the "Base URL" and the "Dashboard ID." Click "Close."
  5. Repeat the same process for the general dashboard. Select products again, as we will update this once the app has generated data. Note that the "Base URL" will be the same for both dashboards but the "dashboard ID" will be different so please take note of it.
Note: You will need the base URL and dashboard IDs to set up your environment variables later (CHARTS_EMBED_SDK_BASEURL, DASHBOARD_ID_PRODUCT, DASHBOARD_ID_GENERAL).
Setting up Atlas Charts will provide you with visually appealing and insightful dashboards to monitor product information and overall analytics, enhancing your decision-making process and improving the efficiency of your inventory management system.
Set up the database trigger for autoreplenishment
Automate inventory replenishment by setting up a database trigger in MongoDB Atlas. Follow these steps to enable the trigger:
  1. Navigate to the "Data Services" section within Atlas. In the sidebar menu, click on "Triggers."
  2. For first-time users of Triggers, select your data source and then click "Get started." For returning users, simply select "Add Trigger."
  3. Choose the trigger type as "Database." Under "Trigger Source Details," provide a name for the trigger and select your cluster, database, and the products collection. Set the operation type to "Update" only. Ensure that both "Full Document" and "Document Preimage" are enabled.
  4. In the "Function" section, replace the default code with the code available at /data/triggers/autoreplenishment.js.
Important: Make sure you replace the <your-cluster-name> placeholder with your actual cluster name in lines 5 and 6.
Let’s dive deeper into the trigger function.
First, we will declare the collections that our function is going to use orders, to automatically place a new order if a low-stock event is detected, and products, the collection that is being monitored to detect low-stock (changeEvent.ns.coll).
We will define the pattern for the kind of changes that we want to monitor. In this case, we are interested in changes in the stock amount. The attribute stock is defined as an array of different stock locations. Our data model reserves the 0 position for the in-store stock. This is the stock we want to monitor.
Then, we just need to iterate over all the updated fields of the change event that has activated our trigger function. That’s what the for loop is used for. Inside of it, we will filter out those fields that don't match our previously defined pattern. If the pattern matches, that means the in-store stock amount has changed. When the result of this change is the in-store stock amount going below the defined threshold, the automatic replenishment process will kick off, creating an order, placing it, and, in the case of this demo app, simulating the arrival after the estimated delivery time.
To create the order, we just need to define an order object with the necessary attributes. We will need to calculate the amount to order from the difference between the current amount and the target amount. For this demo app, we can define any static user_id, as we will not be performing user-based analytics.
Once the order is created, we will need to place it. This means inserting the newly created order in the corresponding collection. Then, we will update the products collection to reflect the stock amount that has been ordered. This implies subtracting the amount from the warehouse stock and adding it to the ordered stock, both in the item-specific size stock and the total product stock.
In a production environment, the order arrival and collection would be handled by an external process. But for the sake of simplicity, we will simulate the time in transit of the order, and then update the data simulating the arrival of the order to the store.
We will wait for the defined delivery_time of that particular item. This is meant to be a responsive demo app, so the waiting time shouldn’t be longer than 10 seconds.
Then, the process is similar to the one for placing an order. In this case, instead of inserting a new order, we’ll update the existing one by changing the status to “arrived.” The product stock is again updated by subtracting the stock from ordered and placing it in store, for both the item and total stock.
Back in the Atlas “Add Trigger” menu, open the "Advanced" section and insert the following code into the "Match Expression" field. This expression will ensure that the trigger function is executed only for products marked for auto-replenishment:
Verify that all the configuration details are accurate and click "Save."

App configuration

Cloning the GitHub repository
Follow these steps to clone the GitHub repository to your local machine:
  1. Open your terminal or command prompt.
  2. Navigate to your preferred directory where you want to store the project using the cd command. For example:
  3. Once you're in the desired directory, use the git clone command to clone the repository. Copy the repository URL from the GitHub repository's main page:
  4. After running the git clone command, a new directory with the repository's name will be created in your chosen directory. To navigate into the cloned repository, use the cd command:
Now you have successfully cloned the GitHub repository to your local machine. You can proceed with the next steps to configure and run the inventory management app.
Set up environment variables
Copy the env.local.example file in this directory to .env.local (which will be ignored by Git) as seen below:
Now, open this file in your preferred IDE and update each variable on .env.local.
Remember all of the notes you took earlier? Grab them because you’ll use them now! Also, remember to remove any spaces after the equal sign.
For macOS users, you can navigate to your file or open it from the terminal by running:
  • MONGODB_URI - Your MongoDB connection string to MongoDB Atlas. You can find this by clicking the "Connect" button for your cluster. Note that you will have to input your Atlas password into the connection string.
  • MONGODB_DATABASE_NAME - Your MongoDB database name for inventory management.
  • REALM_APP_ID - This variable should contain the App ID of the MongoDB Atlas App Services app you've created for the purpose of this project.
  • CHARTS_EMBED_SDK_BASEURL - This variable should hold the URL of the charts you want to embed in your application.
  • DASHBOARD_ID_PRODUCT - This variable should store the Atlas Charts dashboard ID for product information.
  • DASHBOARD_ID_GENERAL - This variable should store the Atlas Charts dashboard ID for the general analytics tab.
Please remember to save the updated file.
Run locally
Execute the following commands to run your app locally:
Your app should be up and running on http://localhost:3000! If it doesn't work, ensure that you have provided the correct environment variables.
Also, make sure your local IP is in the Access List of your project. If it's not, just click the "Add IP address" button in the top right corner. This will display a popup menu. Within the menu, select "Add current IP address," and click "Confirm." Empty network access menu with "Add IP address" button on the right

Personalize your App (optional)

Configure your charts
Congratulations! Now your app is up and running… but have you noticed anything odd? Your charts are empty! Let's fix this.
Go to your product-related dashboard, and select "Add Chart" to create product-related charts. These charts will appear under the stock level of each product on the product page of the app. It's a good opportunity to add context to the stock level of each product so you can make informed decisions on replenishment actions.
Consider including a chart showing the number of orders for the last day, grouped by hour. To do this, once you are in the product dashboard, select "Add Chart" and select the orders collection as the data source. Set the chart type to "Discrete Line." Add placement_timestamp in the X axis binned by hour, and _id aggregated using the count operator in the Y axis.
Configuration for discrete line chart type, placement_timestamp binned hourly and periodically in X axis, and _id count aggregated in Y axis
In the filter tab, drag and drop placement_timestamp, and copy the configuration below. This will display orders made in the current day only.
Filter by placement_timestamp on previous 1 day period including current period and custom time zone
Your chart should look like this:
Line chart showing today's orders
Another interesting option is to include a breakdown by size. To do this, add a new chart with orders as the data source, and select "Stacked Column" as the chart type. Set placement_timestamp as the X axis and amount inside the items array as the Y axis. Array fields must be reduced to visualize the data. Select "Unwind array" as the array reduction method, and "SUM" as the aggregate operator. Unwind will set the granularity of the data by item variant (White T-shirt XS, White T-shirt M,...) instead of the general product (White T-shirt).
Finally, to add a breakdown by size, drag and drop the size field located inside the items array into the "Series" option. Again, select "Unwind Array" as the array reduction method.
Configuration for stacked column chart type, placement_timestamp binned hourly and periodically in X axis, items.amount array unwinded and sum aggregated in Y axis, and items.size array unwinded unbinned in series.
Filter by the current day like in the previous chart, and you will get a chart similar to this one:
Stacked columns chart showing today's ordered items by size
For a deeper dive into chart customization and features, explore the official documentation of MongoDB Charts.
Enable real-time analytics
  1. To create a general analytics dashboard based on sales, we will need to generate sales data. Navigate to the control panel in your app by clicking: http://localhost:3000/control.
  2. Then, click the "start selling" button. When you start selling, remember to not close this window as selling will only work when the window is open. This will simulate a sale every five seconds, so we recommend letting it run for a couple of minutes.
  3. In the meantime, navigate back to Atlas Charts to create a general analytics dashboard. For example, you can create a line graph that displays sales over the last hour, minute by minute. Now you'll see live data coming in, offering you real-time insights!
To achieve this, from the general dashboard, click "Add Chart" and select sales as the data source. Select "Discrete Line" in the chart type dropdown menu. Then, you will need to add timestamp in the X axis and quantity in the Y axis.
Configuration for discrete line chart type, timestamp binned by second non-periodically in X axis, and quantity sum aggregated in Y axis
This data will update in real-time, so to better appreciate the variability in real time, we can limit the results to show only sales data from the previous hour. Navigate to the "Filter" menu under the "Chart Type" dropdown menu. Drag and drop the field timestamp, and copy this configuration, inserting your own timezone.
Filter by timestamp on previous 1 hour period including current period and custom time zone
The resulting chart will look like this:
Line chart showing last hour's sales in real-time
Your app is ready to go! For the first time, you may need to refresh the website to see the updated charts, but after that, the charts will update automatically, syncing with the new sales. And this is just an example — feel free to add the charts you consider most useful to this dashboard.
Set up additional indexes
Enhance the performance and responsiveness of your application by setting up additional indexes. Indexes can significantly improve loading times, especially when dealing with large volumes of data.
Unlike search indexes, this type of index configuration requires navigating to the specific collection where you want to establish the index. Here's how you can do it:
  1. Go to the collection where you want to create the index. From there, select the "Indexes" tab.
  2. Create a new index for the collection. For charts that involve filtering by date and product, such as orders and sales charts, consider utilizing a compound index. This type of index involves multiple fields and can significantly speed up query execution.
For example, for the "orders" collection, you might consider creating a compound index like this:
The above index configuration prioritizes sorting by the placement timestamp in descending order and then by the product's _id field in ascending order.

Additional resources

Congratulations! Your inventory management app is ready to go. Throughout this tutorial, we've covered multiple MongoDB topics. Here's a quick recap of the key learnings:
  • Real-time alerts: Implement real-time low-stock alerts in your front end using Change Streams.
  • Workflow automation: Leverage database triggers to automate stock replenishment workflows.
  • Real-time analytics: Stay on top of your data, analyze trends, and make informed decisions in a timely manner thanks to Atlas Charts.
  • Single view of inventory: Take advantage of the flexibility of the document model to create a comprehensive single view of inventory.
Remember that this is just the beginning. Feel free to explore, tweak, and enhance your inventory management system to fit your own needs.
Curious for more? Learn how MongoDB is helping retailers to build modern consumer experiences. Check the additional resources below:

Facebook Icontwitter iconlinkedin icon
Rate this tutorial

A Free REST API for Johns Hopkins University COVID-19 dataset

Nov 16, 2023 | 5 min read

Atlas Search is a Game Changer!

Dec 07, 2022 | 2 min read

How to work with Johns Hopkins University COVID-19 Data in MongoDB Atlas

Nov 16, 2023 | 8 min read

Migrating PostgreSQL to MongoDB Using Confluent Kafka

Dec 11, 2023 | 10 min read
Table of Contents