MongoDB

On the journey to broadening my horizons, I often wondered what a non-relational Database would like on a personal monthly budget application. Thinking about the data being stored, it would need a collection of different flexible tables.
In a few different Hackathons, I have heard mention of MongoDB, although I did not know much about it. MongoDB uses NoSQL instead of a relational format to provide flexibility and primarily focuses on documents. With the flexibility of NoSQL, it would be nice to have a collection of receipts without having column restrictions.
Feeling adventurous, I decided to delve into the world of non-relational databases. Before installing MongoDB, I need to know what a NoSQL database is and what type of data it can store.
NoSQL versus RDBMS
In a typical Relational Database Management System (RDBMS), tables are linked together using keys. A NoSQL database is non-relational, meaning it is based on the documents themselves instead of the relation between them. In our case, this means the database can store a collection of items instead of typical records.
Because there is no relationship, this type of Database does not require the use of foreign keys. This means that collections can house documents and output data without the use of JOINs or Foreign Keys. MongoDB also does not require the use of schemas. This makes setting up MongoDB much simpler and requires less effort as compared to normalizing a relational database.
How is MongoDB Different
When we typically think of databases, relational databases are the first to come to my mind as that is what I have been using in my previous projects.
Relational databases use what is known as the ACID (atomicity, consistency, isolation, durability) theorem. This focuses on the rules of the database and ensures the uniqueness of records. It is also about keeping consistent schemas or table formats.
NoSQL uses the CAP theorem (consistent, available, partition tolerant). This challenges the designer to plan, as network partitions cannot always guarantee perfect consistency and perfect availability. It is made to be spread across nodes within a distributed system, and attempts to contain the same values in all, but cannot guarantee 100%.
As mentioned previously, MongoDB stores data as documents. When stored, data is kept in JSON (JavaScript Object Notation) format. This allows for fields to be embedded, such as using an array of values as opposed to creating a separate relational table. This allows for a more straight-forward design, and fewer tables to clutter memory. The related values, instead, can be held within a document.
Now that we have a general outlook on MongoDB, we can begin the installation.
Installing MongoDB on Ubuntu
MongoDB has a rather clear set of instructions for downloading on a range of systems. In our case, we will be looking at how to install on Ubuntu. Documentation for Ubuntu or other systems can be found here. To get the package, run this command:
wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add –
The response should be "OK". If there were any issues running this command, you may need to also download gpg with these commands:
wget https://download.docker.com/Linux/ubuntu/gpg
Once finished downloading, you can add the key:
sudo apt-key add gpg
The response should be "OK". Now that we have access to Mongodb, we can copy the necessary files to our own systems. Because I am running Ubuntu 16.04, we need to install version "xenial".
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
Now that it is installed, you must update:
sudo apt-get update
It is important to know which version of Ubuntu you have installed. Ubuntu 16.04 will use "xenial", 18.04 will use "bionic", and 20.04 will use "focal". If you do not have the correct version of Mongo installed, the next steps will throw a broken package error.
With the correct version installed, we are now ready to install MongoDB’s packages:
sudo apt-get install -y mongodb-org
As apt-get is upgraded, packages will also upgrade to newer versions. Because our version of Ubuntu is not equipped to run other versions, we have to make sure it cannot be updated. To do this, we can use the following lines of code run separately to put a hold on each:
echo "mongodb-org hold" | sudo dpkg --set-selections
echo "mongodb-org-server hold" | sudo dpkg --set-selections
echo "mongodb-org-shell hold" | sudo dpkg --set-selections
echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
echo "mongodb-org-tools hold" | sudo dpkg --set-selections
Congratulations, MongoDB is now installed and ready to go. Now, all we must do is start the service:
sudo systemctl start mongod
Much like other services, we can also stop or restart. For now, we will check the status:
sudo systemctl status mongod

Checking our output, it looks like we are ready to get started.
Creating The First MongoDB Collection
To open the command-line version of Mongo, which we will be using, the command is simple:
mongo

Now we are ready to start our first collection for the receipt application. Unlike many other database engines, we do not need to create the database before using it. We can simply instruct Mongo to use the database of our choice, and if it does not already exist it will be automatically created:
use Receipts

To check what database we are using, we can check with the following command:
db

In our new database, we want to create the first collection. NoSQL does not contain typical SQL syntax, as its name would suggest, instead opting for straight forward coding. With the collection, column titles are not required. Instead, the collection is created with a name, then the list of options. To see a comprehensive list of options, visit this website. The first collection will not need any of the options, so only the name is needed:
db.createCollection("Grocery")

Now that the collection has been created, the first example of data can be added. To add, the DB is used, accompanied by the collection name and command insert. The data to insert looks very similar to a JSON object. Because this is not a relational database, it is not necessary to break it down into a detailed level. Instead, we can add the details as an array into the document. Several documents may also be inserted at one time, but for now, just one will be added. Like a JSON object, list the key name then the value.
db.Grocery.insert({Location: "Giant Eagle", Total" 9.69, Coupon: 0.99, User: "Mike", CreatedDate: new Date(), TransactionDate "2020-12-12", Items: [{ProductName: "Milk", UnitPrice: 2.99, Quantity: 2}, {ProductName: "Wheat Bread", UnitPrice: 0.99, Quantity: 2}, {ProductName: "Cat Food Can", UnitPrice: 0.68, Quantity: 4}]})
If done correctly, the output will look like this:

In this code, an Items array was used to store the detail level of the receipt, or what was actually purchased. The nice part about having a flexible collection is that NULL values can be avoided. In this case, there is a coupon. However, if the next grocery receipt does not have a coupon, we can simply not add the key. Likewise, if a gift card were to be used, the key could be added.
With the sample data added, now we need to see the output. To do so, we can use a find command on the collection. Using a "pretty" function with this command also makes the output readable:
db.Grocery.find().pretty();

Conclusion
To sum things up, we discussed what MongoDB is, and how NoSQL is a flexible format with no table relationships. This type focuses heavily on documents as opposed to records. The structure is powerful and could be useful for more dynamic collections that require versatility and availability.
For Receipt tracking, MongoDB will be a good fit. This way, I will not have to have so many NULL values and can create dynamic documents for different grocery stores more easily.
Now that the Grocery collection is created, I will need to create other collections for types of receipts before the Budgeting application can be created. Next time, we can flush out the rest of the database, and learn more about the syntax as well as how to filter results. Until then, cheers!
References
https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/
https://beginnersbook.com/2017/09/mongodb-create-collection/
https://docs.mongodb.com/manual/reference/method/db.collection.insert/
https://stackoverflow.com/questions/24985684/mongodb-show-all-contents-from-all-collections
https://kb.objectrocket.com/mongo-db/how-to-add-elements-into-an-array-in-mongodb-1195
https://www.tutorialspoint.com/inserting-the-current-datetime-in-mongodb
https://docs.mongodb.com/manual/reference/method/db.createCollection/
https://www.voltdb.com/blog/2015/10/disambiguating-acid-cap/