PP | Mongo Shop
Introduction
We want to build a small database for an e-commerce application.
We interviewed the client and she gave us the following requirements for the application:
- She wants to store products with some information
- She needs to save the client information
- Should be able to look the shopping history of every client
- Products can have a category
- Users can review products and rate them by assigning 1 to 5 stars
With this information, we should be able to get started in modeling our Mongo Database. Ready?
Modeling the Data
First of all we need identify the entities in order to create our collections.
Collections
There are differents ways to design the structure. If we come from the world of SQL an approach can be, 4 collections: Users, Products, ShoppingCarts and Reviews. But we are in MongoDB were we can embed documents and we will follow the proposed structure.
- Users
- ShoppingCarts
- Products
- Reviews
The structured proposed is 2 collections users
and products
, inside the collection users
we will store the historical purchases. In the products
collection we will have the reviews of each product.
Each of these collections will have inside the information that we need to store.
Data Model
Once we define our collections, we should define what fields the documents inside the collections will have. Once again, there are many different ways of doing this, but for this exercise, we are going to model the database like this:
Sample User collection
{
"_id": ObjectId("582e3c59eb1b8eb7be087448"),
"firstName": "John",
"lastName": "Smith",
"dateBirth": ISODate("2016-12-10T18:28:09.369Z"),
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021"
},
"shoppingCart": [
ObjectId("582e3dd006a0c0b81841f47e"),
ObjectId("582e3cc7b03b5db7dd616cc8")
]
}
Sample Products Collection
{
"_id": ObjectId("582e3dd006a0c0b81841f47e"),
"name": "WiredTiger T-shirt",
"description":"Crafted from ultra-soft combed cotton, this essential t-shirt features sporty contrast tipping and MongoDB's signature leaf.",
"category":"Apparel",
"reviews": [
{
"name": "Shannon",
"comment": "This is so warm and comfortable.",
"stars": 2,
"date": "2016-11-10T18:28:09.369Z"
},
{
"name": "Shannon",
"comment": "This is so warm and comfortable.",
"stars": 3,
"date": "2016-11-10T18:28:09.369Z"
}],
"price":12.0
}
PART 1 | CRUD in MongoShell
1.1 | Create a database name
The first step to start the exercise is to create our own database. Let's call it myShop
:
$ mongo
MongoDB shell version: 3.2.11
connecting to: test
> use myShop
switched to db myShop
users
collection
1.2 | Insert our first users in Insert this user in the users
collection:
{
"firstName": "John",
"lastName": "Smith",
"dateBirth": ISODate("2016-12-10T18:28:09.369Z"),
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021"
}
}
After you insert it, don't forget to check that the user is inserted correctly and add yourselves as users in the collection too!
products
collection
1.3 | Insert our first products in Now let's add a product to our products
collection:
{
"name": "Water Bottle",
"description":"High quality glass bottle provides a healthier way to drink. Silicone sleeve provides a good grip, a see-through window, and protects the glass vessel. Eliminates toxic leaching that plastic can cause. Innovative design holds 22-1/2 ounces. Dishwasher safe",
"category":"Kitchen",
"price":23.0
}
Dont' forget to check that the product is inserted correctly and insert a product for each of you :)
1.4 | Getting Started with queries
-
Create a purchase with some products for the user.
Remember that purchases are the elements inside the
"shoppingCart"
array property of auser
. -
List all
products
-
List all
products
with the samecategory
-
Delete a
product
-
Write a review for one product
"reviews": [
{
"name": "Shannon",
"comment": "This is so warm and comfortable.",
"stars": 2,
"date": "2016-11-10T18:28:09.369Z"
}
]
Welcome the NodeJS driver
Until now we played with MongoShell, In Part 2 let's play with MongoDB Driver for NodeJS.
Connecting to Mongo Database
To make the connection between NodeJS and MongoDB we use the MongoDB Driver, which is a package we need to install:
$ npm install mongodb --save
The code below is a basic script to connect to your local MongoDB.
const MongoClient = require('mongodb').MongoClient;
const dbServer = 'localhost';
const dbPort = '27017';
const dbName = 'ironhackshop';
const connectionURL = `mongodb://${dbServer}:${dbPort}/${dbName}`;
// Use connect method to connect to the server
MongoClient.connect(connectionURL, function(error, db) {
if(error) { console.log("Error connecting to server", error); return;}
console.log("Connected successfully to server")
// Make your queries here
db.close();
});
First we are importing MongoClient
from mongodb
, that is the driver package for NodeJS.
We use MongoClient.connect()
to establish the connection to MongoDB. Connect recieves two argumments, one is the database's URL, and the other is a callback that will be called when the connection to the Database is available.
This callback will have two parameters:
error
, if there are any problemsdb
: the database object we will use to perform queries
How to perform queries in NodeJS
In order to perform queries with the driver, we need to use the db
object returned in the connection callback.
The db
object has a method db.collection()
that allows us to performa a find query on that collection.
db.collection('products').find().toArray((error, products) => {
assert.equal(error, null);
console.log('All Products: ', products)
})
We can invoke collection('<collectionName>')
method to perform queries on a particular collection.
Over collection we can apply almost the same methods that we were applaying in MongoShell, but we strongly recommend check the documentacion of MongoDB Driver.
Let's get our hands dirty!!!!
PART 2 | CRUD in NodeJS driver
Lab 0 | Setup Repository
You are gonna build an e-commerce terminal application.
$ git clone https://github.com/ironhack/lab-mongo-shop
Once you've downloaded the repo, enter in that folder and type:
$ cd lab-mongo-shop
$ npm install
$ npm start
The project has the following structure
Folder | Description |
---|---|
/data |
Folder that contain the json for collections |
database.js |
Class to connect to MongoDB Driver |
questions.js |
Class to interact through the prompt terminal and ask questions |
main.js |
Our main file, where everything starts |
Open the project with your editor
Lab 1 | Insert User
Open database.js
. This is the file you have to perform the differents queries.
Find the method insertUser(<user>, callback(error, result))
we call the method this.connect
and inside his callback, if there is an error we invoke our callback with the error if everything went well we will use database
object to connect to our DB.
insertUser(user, callback = (error, result) => {}){
this.connect((error, database) => {
if (error){
callback(error);
} else {
// LAB 1
// Implement the query to insert a user
// remeber once it's finish to comment callback('Error inserting user');
callback('Error inserting user');
}
});
}
In line 9 type database.collection('users').insertOne();
If we check the documentation insertOne(doc, options, callback)
doc
is the document to insertoptions
we are not gonna use it nowcallback
is the command result callback.
...
} else {
// LAB 1
// Implement the query to insert a user
// remeber once it's finish to comment callback('Error inserting user');
database.collection('users').insertOne(user, callback);
callback('Error inserting user');
}
...
user
is the document to insert and we are passing callback from insertOne
invoked inside insertOne
to our callback in line 1.
We are doing this because, the callback from insertOne has the same signature than our callback (line 1).
Let's try it in our first function:
$ npm start
Select option 1 > option 1 "User > Insert a user". follow the instructions.
Once is inserted go to MongoShell and see if was inserted correctly.
Lab Exercises
Perform the different queries, the column Function Name is that you have to finish.
Lab | Description | Function Name |
---|---|---|
1 | Insert a users | insertUser |
2 | List all users | listUsers |
3 | Delete a user | deleteUser |
4 | Insert a product | insertProduct |
5 | List all products | listProducts |
6 | Delete a product | deleteProduct |
7 | Buy a product | addProductToShoppingCart |
8 | Make a review | addReviewToProduct |
// Happy Coding! 😀
Summary
In this exercise we've practised the basics queries in MongoShell also we've learned how to connect NodeJS through MongoDB Driver to the DB.
Extra Resources
Reference API MongoDB Driver MongoDB Driver Website Getting Started