Using NoSQL for relational data.. Why do we choose MongoDB as a database…
By: Paul Allies
Tags: NoSQL, Database, Mongodb

Photo by Tobias Fischer on Unsplash

sources: MongoDB, DynamoDB, the Internet.

When people use the term “NoSQL database”, they typically use it to refer to any non-relational database. Some say the term “NoSQL” stands for “non SQL” while others say it stands for “not only SQL.” Either way, most agree that NoSQL databases are databases that store data in a format other than relational tables.

A common misconception is that NoSQL databases or non-relational databases don’t store relationship data well. NoSQL databases can store relationship data — they just store it differently than relational databases do. In fact, when compared with SQL databases, many find modeling relationship data in NoSQL databases to be easier than in SQL databases, because related data doesn’t have to be split between tables.

NoSQL data models allow related data to be nested within a single data structure or referenced in another document.

Nested Data

Illustrated here is an organization with it’s users.

{

_id: "google",

name: "Google",

users: [

{ _id: "john", name: "John Smith"},

{ _id: "jeff", name: "Jeff Brown"}

]

}

Document Reference Pattern.

When we think of modelling NoSQL in a RDBMS way, we’ll need to reference documents in other collections to link or join 2 pieces of related data.

// document in organization collection

{

_id: "google",

name: "Google"

} // document in user collection

{

_id: "john",

name: "John Smith",

organization_id: "google" } {

_id: "jeff",

name: "Jeff Brown",

organization_id: "google" }

So to find an organization and all the users in one query we need to use the aggregation framework:

db.getCollection('organization')

.aggregate([

{

$match: { _id: "google"}

},

{

$lookup: {

from: "user",

localField: "_id",

foreignField: "organization_id",

as : "users"

}

}

])

Result

{

"_id" : "google",

"name" : "Google",

"users" : [

{

"user_id" : "john",

"name" : "John Smith",

"organization_id" : "google"

},

{

"user_id" : "jeff",

"name" : "Jeff Brown",

"organization_id" : "google"

}

]

}

When using joins, our queries don’t scale. The computation cost rises as data footprint increases.

Adjacency list pattern

Let’s try the Adjacency list pattern(typically used in DynamoDB) for storing data:

Use one collection for all data. Let’s call it “DATA”

//organization document in DATA collection

{

"_id": "org#google",

"name": "Google",

}

{

"_id": "org#microsoft",

"name": "Microsoft",

}

{

"_id": "org#apple",

"name": "Apple",

} //user document in DATA collection

{

_id: "org#google#user#john",

name: "John Smith"

}

{

_id: "org#google#user#jeff",

name: "Jeff Brown"

}

{

_id: "org#apple#user#tim",

name: "Tim Cook"

}

Let’s try to find an organization and all the users in one query.

db.getCollection('DATA').find({_id: {$regex: /^org#google/}})

The query finds all documents in the DATA collection starting where _id starts with “org#google”

Result

{

"_id" : "org#google",

"name" : "Google"

} {

"_id" : "org#google#user#jeff",

"name" : "Jeff Brown"

} {

"_id" : "org#google#user#john",

"name" : "John Smith"

}

We can retrieve the same data without a join, without adding indexes, without using the aggregation framework