The Practice Shop Database

MongoDB · Lesson 5 of 28 7 min read Updated

From this lesson on, almost every example in the course runs against one small database called shop. It belongs to an online store that sells computer and mobile accessories to customers across India. Using the same data everywhere means you can compare results between lessons and you always know what a query should return.

In this lesson you will create the database with one script, look at a document from each collection and learn how the three collections connect.

The three collections

The shop database has three collections. A collection is a group of related documents, much like a table in SQL.

CollectionDocumentsWhat each document describes
customers8A person who has an account: name, email, city, join date
products10An item for sale: name, category, price in rupees, stock, tags
orders12One purchase: who bought, when, the status, the items and the total

The data is deliberately small. Twelve orders are enough to practise grouping, sorting and joining, and small enough that you can check every answer by eye.

The data script

Create a folder for your MongoDB practice files, for example C:\mongo on Windows or ~/mongo on Linux and macOS. Inside it, create a file named shop-data.js and paste the three parts below into it, one after another.

The first part switches to the shop database, deletes it if it already exists, and adds the customers:

MongoDB Shell
// shop-data.js: builds the practice database used in this course
db = db.getSiblingDB('shop');
db.dropDatabase();

db.customers.insertMany([
  { _id: 1, name: 'Aarav Sharma', email: 'aarav@example.com', city: 'Jaipur', joined: ISODate('2025-01-14'), premium: true },
  { _id: 2, name: 'Priya Nair', email: 'priya@example.com', city: 'Kochi', joined: ISODate('2025-03-02'), premium: false },
  { _id: 3, name: 'Kabir Singh', email: 'kabir@example.com', city: 'Rohtak', joined: ISODate('2025-06-21'), premium: true },
  { _id: 4, name: 'Meera Iyer', email: 'meera@example.com', city: 'Pune', joined: ISODate('2025-09-10'), premium: false },
  { _id: 5, name: 'Rohan Gupta', email: 'rohan@example.com', city: 'Lucknow', joined: ISODate('2026-01-05'), premium: false },
  { _id: 6, name: 'Ananya Das', email: 'ananya@example.com', city: 'Pune', joined: ISODate('2026-02-18'), premium: true, referredBy: 1 },
  { _id: 7, name: 'Farhan Khan', email: 'farhan@example.com', city: 'Jaipur', joined: ISODate('2026-04-30'), premium: false, referredBy: 3 },
  { _id: 8, name: 'Isha Verma', email: 'isha@example.com', city: 'Kochi', joined: ISODate('2026-07-12'), premium: false }
]);

The second part adds the products. Two of them carry an extra specs sub-document, because in MongoDB documents in the same collection do not need identical fields:

MongoDB Shell
db.products.insertMany([
  { _id: 101, name: 'Wireless Mouse', category: 'Accessories', price: 799, stock: 120, rating: 4.3, tags: ['wireless', 'computer'] },
  { _id: 102, name: 'Mechanical Keyboard', category: 'Accessories', price: 3499, stock: 45, rating: 4.6, tags: ['computer', 'gaming'] },
  { _id: 103, name: '27-inch Monitor', category: 'Displays', price: 15999, stock: 12, rating: 4.4, tags: ['computer', 'office'], specs: { size: '27 inch', resolution: '2560x1440' } },
  { _id: 104, name: 'USB-C Cable', category: 'Accessories', price: 299, stock: 300, rating: 4.1, tags: ['cable', 'mobile'] },
  { _id: 105, name: 'Bluetooth Earbuds', category: 'Audio', price: 2499, stock: 60, rating: 4.0, tags: ['wireless', 'mobile', 'music'] },
  { _id: 106, name: 'Laptop Stand', category: 'Accessories', price: 1299, stock: 0, rating: 4.5, tags: ['office'] },
  { _id: 107, name: 'Portable SSD 1TB', category: 'Storage', price: 6999, stock: 25, rating: 4.7, tags: ['storage', 'backup'], specs: { capacity: '1TB', port: 'USB-C' } },
  { _id: 108, name: 'Learn Python Book', category: 'Books', price: 649, stock: 40, rating: 4.8, tags: ['books', 'learning'] },
  { _id: 109, name: 'HD Webcam', category: 'Accessories', price: 1899, stock: 18, rating: 3.9, tags: ['video', 'office'] },
  { _id: 110, name: 'Power Bank 20000mAh', category: 'Mobile', price: 1499, stock: 75, rating: 4.2, tags: ['mobile', 'travel'] }
]);

The third part adds the orders and prints a count of each collection so you can see that everything worked:

MongoDB Shell
db.orders.insertMany([
  { _id: 1001, customerId: 1, date: ISODate('2026-08-03T10:15:00Z'), status: 'delivered', payment: 'UPI',
    items: [{ productId: 101, name: 'Wireless Mouse', price: 799, qty: 1 }, { productId: 104, name: 'USB-C Cable', price: 299, qty: 2 }], total: 1397 },
  { _id: 1002, customerId: 2, date: ISODate('2026-08-07T14:40:00Z'), status: 'delivered', payment: 'card',
    items: [{ productId: 103, name: '27-inch Monitor', price: 15999, qty: 1 }], total: 15999 },
  { _id: 1003, customerId: 1, date: ISODate('2026-08-15T09:05:00Z'), status: 'delivered', payment: 'UPI',
    items: [{ productId: 107, name: 'Portable SSD 1TB', price: 6999, qty: 1 }], total: 6999 },
  { _id: 1004, customerId: 3, date: ISODate('2026-08-21T18:30:00Z'), status: 'delivered', payment: 'COD',
    items: [{ productId: 102, name: 'Mechanical Keyboard', price: 3499, qty: 1 }, { productId: 101, name: 'Wireless Mouse', price: 799, qty: 1 }], total: 4298 },
  { _id: 1005, customerId: 4, date: ISODate('2026-09-02T11:20:00Z'), status: 'cancelled', payment: 'card',
    items: [{ productId: 105, name: 'Bluetooth Earbuds', price: 2499, qty: 1 }], total: 2499 },
  { _id: 1006, customerId: 5, date: ISODate('2026-09-09T16:45:00Z'), status: 'delivered', payment: 'UPI',
    items: [{ productId: 108, name: 'Learn Python Book', price: 649, qty: 2 }], total: 1298 },
  { _id: 1007, customerId: 6, date: ISODate('2026-09-18T12:10:00Z'), status: 'shipped', payment: 'UPI',
    items: [{ productId: 110, name: 'Power Bank 20000mAh', price: 1499, qty: 1 }, { productId: 104, name: 'USB-C Cable', price: 299, qty: 1 }], total: 1798 },
  { _id: 1008, customerId: 3, date: ISODate('2026-09-25T19:55:00Z'), status: 'delivered', payment: 'UPI',
    items: [{ productId: 109, name: 'HD Webcam', price: 1899, qty: 1 }], total: 1899 },
  { _id: 1009, customerId: 2, date: ISODate('2026-10-04T08:30:00Z'), status: 'shipped', payment: 'card',
    items: [{ productId: 105, name: 'Bluetooth Earbuds', price: 2499, qty: 2 }], total: 4998 },
  { _id: 1010, customerId: 7, date: ISODate('2026-10-11T13:00:00Z'), status: 'pending', payment: 'COD',
    items: [{ productId: 106, name: 'Laptop Stand', price: 1299, qty: 1 }, { productId: 101, name: 'Wireless Mouse', price: 799, qty: 1 }], total: 2098 },
  { _id: 1011, customerId: 1, date: ISODate('2026-10-19T20:25:00Z'), status: 'pending', payment: 'UPI',
    items: [{ productId: 102, name: 'Mechanical Keyboard', price: 3499, qty: 1 }], total: 3499 },
  { _id: 1012, customerId: 4, date: ISODate('2026-10-24T10:50:00Z'), status: 'delivered', payment: 'UPI',
    items: [{ productId: 108, name: 'Learn Python Book', price: 649, qty: 1 }, { productId: 110, name: 'Power Bank 20000mAh', price: 1499, qty: 1 }], total: 2148 }
]);

print('customers:', db.customers.countDocuments());
print('products:', db.products.countDocuments());
print('orders:', db.orders.countDocuments());

Load the data

Open a terminal in the folder that holds shop-data.js and start mongosh (for Atlas, use your connection string as shown in Install MongoDB, mongosh & Compass). Then run the script with load() and switch to the new database:

MongoDB Shell
load('shop-data.js')
use shop
Output
customers: 8
products: 10
orders: 12
true
switched to db shop

The three lines come from the print() calls, true is the return value of load(), and the last line confirms that db now points at shop. If load() cannot find the file, give the full path with forward slashes, such as load('C:/mongo/shop-data.js').

A first look at each collection

Fetch one order by its _id with findOne(). You will learn the method properly in Find Documents; for now, just read the shape of the result:

MongoDB Shell
db.orders.findOne({ _id: 1001 })
Output
{
  _id: 1001,
  customerId: 1,
  date: ISODate('2026-08-03T10:15:00.000Z'),
  status: 'delivered',
  payment: 'UPI',
  items: [
    { productId: 101, name: 'Wireless Mouse', price: 799, qty: 1 },
    { productId: 104, name: 'USB-C Cable', price: 299, qty: 2 }
  ],
  total: 1397
}

Order 1001 belongs to customer 1, Aarav. It contains an array of two items, and each item is a small embedded document. The total is 799 + 2 × 299 = ₹1,397. Notice that mongosh shows the date in full, with milliseconds and a Z at the end, which means UTC time.

How the collections connect

The collections link to each other through _id values, in the same way a foreign key links SQL tables:

  • orders.customerId holds the _id of a document in customers.
  • orders.items.productId holds the _id of a document in products.
  • customers.referredBy, which only two customers have, holds the _id of the customer who referred them.

Each order item also copies the product's name and price. That is a deliberate design choice, not an accident. If the shop raises the price of the mouse next month, Aarav's old order must still show the ₹799 he actually paid. You will meet this idea again in Schema Design: Embed or Reference.

A few facts about the data are worth remembering, because many later results depend on them:

  • Isha (customer 8) has no orders yet.
  • The Laptop Stand (product 106) is out of stock: its stock is 0.
  • Order 1005 is cancelled, two orders are pending and two are shipped; the other seven are delivered.
  • The _id values are small numbers chosen by us. Real applications usually let MongoDB create an ObjectId, as you saw in BSON Data Types & ObjectId. Readable numbers simply keep the outputs short.

Common mistakes

  • Forgetting use shop. If your prompt still says test>, every query looks in the empty test database and returns nothing. Switch first.
  • Running the script from the wrong folder. load() looks for a relative path in the folder where you started mongosh. Use the full path if in doubt.
  • Breaking the file while pasting. A missing comma or bracket gives a SyntaxError with a line number. Compare that line with the code above.
  • Changing the data and forgetting. If a result does not match the lesson, reload the script and try again.

Key points

  • The shop database has three collections: customers (8), products (10) and orders (12).
  • One script, shop-data.js, creates everything; run it with load() and then use shop.
  • Running the script again resets the database to its starting state.
  • Orders reference customers by customerId and products by items.productId.
  • Order items copy the product name and price so old orders keep the price that was paid.

Exercise

Load the shop data, switch to the shop database and fetch the product whose _id is 107. Then fetch the customer whose _id is 6 and note which field she has that most other customers do not.

Show solution
MongoDB Shell
load('shop-data.js')
use shop
db.products.findOne({ _id: 107 })
db.customers.findOne({ _id: 6 })

Product 107 is the Portable SSD 1TB at ₹6,999 with a specs sub-document. Customer 6 is Ananya Das from Pune; she has a referredBy field with the value 1, because Aarav referred her. Only Ananya and Farhan have this field.

Quick Quiz

1. Which collection stores the price a customer actually paid for an item?

2. What does running load('shop-data.js') a second time do?

3. How does an order point to the customer who placed it?

Learn MongoDB with a mentor

Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call