Understanding Modeling Relationships in NoSQL Database - Part One

Understanding Modeling Relationships in NoSQL Database - Part One

Modeling Relationships in NoSQL Database can be done through

  • Reference (Normalization)

  • Embedded Document (Denormalization)

Normalization Adding a reference of a collection in another collection, for example

let user = {
  id: "4y56yui33o",
  name: "jade"
}
let post = {
  title: "hashnode article",
  user: "4y56yui33o"
}

user id reference is used in post model

Denormalization Add a full doument oject of another collection, example

let post = {
  name: "hashnode article",
  user: {
    id: "4y56yui33o",
    name: "jade"
  },
};

full user object collection is a reference in post collection.

  • Normalisation gives us consistency since we can update user details in one place, all post collection that reference user will see the updated user collection, but anytime we want to query a post, we need another query to get the related user. This approach gives us consistency, but the is a drawback in performance since we will need an additional query to get user details, we will see this in the node.js code example
  • Denormalisation, we can load the post and user model using a single query, thus give us improve performance, but this leads us to more work when we want to update user collection since multiple posts have user collection, this gives us performance headway but a drawback in consistency.

Choosing between Normalization and Denormalisation is a trade-off between query performance and consistency.

NodeJs Implementation of Normalisation In NoSQL database

const mongoose = require("mongoose");

mongoose
  .connect(
    "localhost:dbmodel.db",
    { useUnifiedTopology: true, useNewUrlParser: true, useCreateIndex: true }
  )
  .then(() => console.log("Connected to MongoDB..."))
  .catch((err) => console.error("Could not connect to MongoDB...", err));

const User = mongoose.model(
  "User",
  new mongoose.Schema({
    name: String,
    email: String,
  })
);

const Post = mongoose.model(
  "Post",
  new mongoose.Schema({
    title: String,
     body:  String,
    user: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
    },
  })
);

async function createUser(name, email) {
  const user = new User({
    name,
    email,
  });

  const result = await user.save();
  console.log(result);
}

async function createPost(title, body, user) {
  const post = new Post({
    title,
    body,
    user,
  });

  const result = await post.save();
  console.log(result);

}

async function posts() {
  const courses = await Post.find()
    .populate("user", "name -_id")
    .select("title body user");
  console.log(courses);
}

//posts()

//createUser("Jade", "jade@gmail.com");

//createPost("How to make a connection with MongoDB ", "from the code above, we //started by making our connection with MongoDB using mongoose", //"5fec12ffc416900d1bdae4a1");

from the code above, we started by making our connection with MongoDB using mongoose.

The next was setting up our model for user and post with their schema, in the post schema, as you can see, we made reference to the user using it's objectId, this is how we implement Normalization in NoSQL Database.

createUser function allows us to create a user while the createPost function allows us to create a post.

If you uncomment the createUser function you and run node test.js in your terminal(test.js is the name of the file), you should get this in the console

{
  _id: 5fec1dcac5c8281c6bdad307,
  name: 'Jade',
  email: 'jade@gmail.com',
  __v: 0
}

if you comment out createUser and uncomment out createPost, run node test.js

{
  _id: 5fec1f4ea5a9ee1e86015eba,
  title: 'How to make a connection with MongoDB ',
  body: 'from the code above, westarted by making our connection with MongoDB using mongoose',
  user: 5fec1dcac5c8281c6bdad307,
  __v: 0
}

In order to fetch lists of posts created by a user, we can use the function below. comment createUser and createPost, uncomment posts(). then run node test.js


[
  {
    _id: 5fec1f4ea5a9ee1e86015eba,
    title: 'How to make a connection with MongoDB ',
    body: 'from the code above, westarted by making our connection with MongoDB using mongoose',
    user: { name: 'Jade' }
  }
]

The populate instance allows us to fetch details of reference collection and it accepts two arguments, reference name and the fields we want to fetch from the reference collection.

This is the end of part one, In part two , we will talk about NodeJs Implementation of Denormalisation In NoSQL database

Read Part Two Here