Learning Node.js — Part 7

In our applications, we will develop multiple Models to represent our data. Our data, by default, can and will be connected in a multitude of ways, our objects will be related. To support the associations that our Models have with each-other, Mongoose has to be told in what ways our Models interact. In relational databases, like PostgreSQL, there is a concept of relationship (ex: foreign keys). This isn’t the case with NoSQL databases; don’t truly have a relationship.

***Relational and NoSQL database trade off: Query performance vs. consistency

Approaches to Work With Related Objects:

Normalization: Using References

Line 6 does NOT establish a direct relationship between the song and the musician. There is no enforced data integrity¹, the id is being set manually, and there is plenty of room for error doing it this way.

Upside: Consistency

Downside: Slower bc queries don’t run as fast as possible

Denormalization: Using Embedded Documents

With denormalization, we embed the song document inside the musician document.

Upside: If changes are made, they potentially need to be updated in multiple objects

Downside: Fast, single queries, all information is directly in the one object

Hybrid Approach

Gives us a snapshot of our data at a given point in time

Setting Up A Relationship — Song belongs to Musician

Terminal shows:

MongoDB Compass Shows:

! Be careful bc if we store the reference to an invalid musician id, mongo doesn’t know it’s invalid, and it will save it anyways (example in the code above)!

.populate()

This method follows the path to the given property (argument). The ‘ref’/reference listed as an attribute of musician when we instantiated a new Song:

Terminal:

To specify properties that you want to include, use the 2nd argument of .populate():

  • .populate(‘musician’, ‘name’)

To exclude something, for example ‘id’:

  • .populate(‘musician’, ‘-_id’)

Embedded Documents

Aka: Sub-documents

Embedded Documents can not be saved on their own, they are only saved in the context of their parent.¹

Array of Sub-documents:

Terminal:

Node Package: Fawn

Fawn provides the ability to carry out edits on a mongoDB database as a series of steps. If an error occurs on any of the steps, the database is returned to its initial state (its state before the transaction started). It’s based on the two phase commit system². Terminal command: npm i fawn

  • Fawn creates a new collection (ojlinttaskcollections) to perform the two phase commit transactions. When we .run() these types of tasks, it creates a new document in that collection, completing all of the tasks in our transaction independently. Once all of the operations are complete, it deletes the collection.

ObjectID in MongoDB

example: _id: ObjectId(“608ea873f5c4bb0795d18b79”)

  • 24 characters — every two characters represent a byte
  • 12 bytes to uniquely identify a document in MongoDB
  • First 4 bytes represent the time stamp of when document created
  • Next 3 bytes: machine identifier — no two machines have the same identifier
  • Next 2 bytes: process identifier — same machine, same document but created during different process
  • Last 3 bytes represent counter — same machine, same process, same second but generate different docs

1 byte = 8 bits (0 or 1) / 1 byte can represent 256 different numbers ( 2 ^ 8)

In 3 bytes we can store (2 ^ 24) = 16m : Counter will only overflow if on the same machine, during the same process we make more than 16m docs, the ObjectID won’t be unique.

MongoDB Driver generates the unique ObjectID. Mongoose is an abstraction built over MongoDB Driver.

create an explicit id in mongoose

Node Package: Joi-objectid

Adds support for validating ObjectId in Joi. It validates that the value is an alphanumeric string of 24 characters in length³. Terminal command: npm i joi-objectid

  1. Node.js Tutorial for Beginners | Programming with Mosh | “https://www.youtube.com/watch?v=TlB_eWDSMt4&t=2349s
  2. Fawn | “https://www.npmjs.com/package/fawn
  3. Joi-objectid | “https://www.npmjs.com/package/joi-objectid

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Osha Groetz

Osha Groetz

93 Followers

Software Engineer. A new addict of ReactJS & Javascript, CSS & APIs, with a little dabbling in Ruby, Ruby On Rails…