Cedric Hopf
Published at 15.03.2021
Always wondered what a NoSQL database and specifically MongoDB is? Then you are exactly right here. In the following, we will explain the strengths and weaknesses of NoSQL databases. You will learn when it makes sense to use such a database and when it makes sense to stick with a more classical and historically known database. To round it all off, we have created an example app with Go that takes a JSON string, stores it in a MongoDB database, and reads the created object from the database again.
In this article, we are going to present the NoSQL database, using MongoDB as a reference. We’ll point out some strengths and weaknesses of NoSQL databases when it is of interest to use such a database and when you should stick with a more classical and historically known database. We will wrap this article up with a code snippet in Go.
Table of Contents
MongoDB was created to work around the shortcomings of the existing databases in 2007 and released two years later, in 2009.
If we take a step back and look at the landscape of 2007-2009: it was the birth of cloud computing and Big Data.
At the time, the Internet was growing exponentially fast, and internet companies started to get thousands, sometimes hundreds of thousands, requests per second. Companies required more and more power to run their application and systems. And unfortunately, existing systems and software of the time (including databases) were just unable to follow such a significant amount of data and requests – they had not been designed nor expected at their inception to handle such load. As a result, whole systems were slowed down and sometimes, in the worst case, completely crashing.
Back to today! MongoDB is a “source-available cross-platform document-oriented database program”(source: Wikipedia)[1]. While this statement sounds like a mouthful, taking the term one by one makes it easy to understand.
Now that we have a better understanding of MongoDB’s history and definition let’s look at what it offers today. At anynines, we believe that there is always a tool best suited for a defined job, so let’s try to figure out how it opposes relational databases and when we should prefer one over the other.
As stated earlier, each record in MongoDB is stored as a document. As stated by the official documentation [2]:
Documents:
A record in a MongoDB collection and the basic unit of data in MongoDB. Documents are analogous to JSON objects but exist in the database in a more type-rich format known as BSON
JSON represents objects derived from JavaScript; however, many programming environments support converting JSON objects into native mapping types.Documents in MongoDB are BSON, a binary data format like JSON but includes additional type data.
Collection:
A grouping of MongoDB documents. A collection is the equivalent of an RDBMS table. A collection exists within a single database. Collections do not enforce a schema. Documents within a collection can have different fields. Typically, all documents in a collection have a similar or related purpose. See Namespaces.
If you want to know more about documents and collections, we would suggest taking a look at the official documentation for documents here [2], but the whole text could be simplified with the following schema:
NOTE:
A document is similar to a record from a SQL perspective, while a collection is similar to a table.
While a traditional SQL database contains fixed and predefined tables to store the data, a NoSQL database can support different types of data structures. This could be a JSON object which is stored in a document or a simple key-value pair.
SQL and NoSQL are like light and dark: they are just two sides of the same coin. Just like there would be no night without day, NoSQL would most probably not exist if SQL was not there before. It is important to remember the relationship between the two, because not one is worse than the other. They just have different use cases and you should favor one or the other depending on your requirements. But we will discuss that later.
Both have fundamental differences:
SQL
NoSQL
relational
Non-relational
Structure Query Language (SQL)
No standard query language
predefined schema
Dynamic schema, unstructured Data
vertically scalable_which means that we increase the number of resources (eg. CPU, Ram, …)_
horizontally scalable_which means that we increase the number of instances (eg. we go from 1 to more instances/server)_
Table based
document, key-value, graph or wide-column stores
As we can see from the table, they are the opposite one to the other.
While it is possible to use an SQL database to do NoSQL work and vice-versa, it should be evident that they will each shine differently depending on the task that is asked out of them.
The following code snippet shows an example application written in Go that takes a JSON string, stores it in a MongoDB database, and reads the created object from the database again.
Code Example
1package main
2
3import (
4 "context"
5 "encoding/json"
6 "log"
7 "time"
8
9"go.mongodb.org/mongo-driver/bson"
10 "go.mongodb.org/mongo-driver/mongo"
11 "go.mongodb.org/mongo-driver/mongo/options"
12)
13
14var jsonData = `{
15 "first_name": "John",
16 "last_name": "Smith"
17}`
18
19func main() {
20 // Client creation
21 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
22 defer cancel()
23 client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://admin:secret@localhost:27017"))
24 if err != nil {
25 log.Fatal(err)
26 }
27 defer client.Disconnect(ctx)
28
29// Parse the given JSON string into a map
30 data := make(map[string]interface{})
31 err = json.Unmarshal([]byte(jsonData), &data)
32 if err != nil {
33 log.Fatal(err)
34 }
35
36collection := client.Database("example").Collection("my-collection")
37 // Store the object in the database
38 response, err := collection.InsertOne(ctx, data)
39 if err != nil {
40 log.Fatal(err)
41 }
42 log.Printf("Inserted ID: %s", response.InsertedID)
43
44// Query an object from the database
45 result := collection.FindOne(ctx, bson.M{
46 "_id": response.InsertedID,
47 })
48 object := make(map[string]string)
49 err = result.Decode(object)
50 if err != nil {
51 log.Fatal(err)
52 }
53 log.Printf("Queried database object: %v", object)
54}
After running the application using `go run main.go
`, it should print the following output:
Code Example
12021/02/12 11:34:10 Inserted ID: ObjectID("602659a2952a3497ed9dccd7")
22021/02/12 11:34:10 Queried database object: map[_id:602659a2952a3497ed9dccd7 first_name:John last_name:Smith]
As you can see from the code snippet, using MongoDB is not more challenging to use than a conventional database from a code perspective. All modern languages have ORM (Object-relational mapping: converting data between incompatible type systems using object-oriented programming languages) that allows developers to quickly translate database entries to language structures or objects – whenever it is from PostgreSQL, MySQL, or MongoDB.
Therefore it is up to the developers to determine which usage they will do of their data; here, we highlighted the strengths of a NoSQL database using MongoDB as an example, and as it was stated, it is excellent for any big data computing. As developers, it is essential to think from the beginning which usage our product will have and what we expect from it and choose our technological stack accordingly. As the saying goes: when you have a hammer, everything looks like a nail. But sometimes, what you are looking for is a screw and a screwdriver.
[1] https://en.wikipedia.org/wiki/MongoDB
[2] https://docs.mongodb.com/getting-started/java/documents/
© anynines GmbH 2024
Products & Services
© anynines GmbH 2024