DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Introduction to Couchbase for Oracle Developers and Experts: Part 2 - Database Objects
  • Manage Hierarchical Data in MongoDB With Spring
  • Spring Data: Data Auditing Using JaVers and MongoDB
  • The Complete Tutorial on the Top 5 Ways to Query Your Relational Database in JavaScript - Part 2

Trending

  • How the Go Runtime Preempts Goroutines for Efficient Concurrency
  • Unlocking AI Coding Assistants Part 2: Generating Code
  • Java’s Next Act: Native Speed for a Cloud-Native World
  • A Guide to Developing Large Language Models Part 1: Pretraining
  1. DZone
  2. Data Engineering
  3. Data
  4. Object Relations in a NoSQL Database

Object Relations in a NoSQL Database

Objects and relations are a crucial part of any application. By letting the database do the job of maintaining this logic, you will save yourself a ton of work.

By 
Jon Erik Solheim user avatar
Jon Erik Solheim
·
Apr. 27, 17 · Analysis
Likes (4)
Comment
Save
Tweet
Share
27.1K Views

Join the DZone community and get the full member experience.

Join For Free

Compared to a traditional relational database (SQL), a document-oriented (NoSQL) database has poor or non-existent support for relations between objects (data schema). A NoSQL datastore persists and retrieves documents (often in JSON format) and any relationship between your documents is something you must implement yourself.

Without any direct support for relations, you’re stuck with the logic and maintenance of objects/relations in your application layer.

This blog post shows how you can leave the job of maintaining object/relations to a database, effectively giving you time to pick from your backlog instead of adding.

Example Application

As a context for this blog post, we'll create a simplified data schema for an issue-tracking application.

An issue-tracking application typically lets customers reports issues, and someone in the organization is selected as a responsible contact for the follow-up and for ultimately resolving the reported issue.

The illustration below shows the three main objects of our application.

illustration

This simplified model has two explicit relations from the issues object:

  1. An issue is linked to one customer.
  2. An issue has one responsible.

The model also has two implicit relations:

  1. A customer can have many issues.
  2. A responsible can have many issues.

Our simple data model reveals that there are four object/relations that must be maintained in our issue tracking application.

Creating a Schema With Relations

With the example above in mind, let's go ahead and show how we can create data consistency and flexibility by using relations in our JSON documents.

Just as in a traditional relational database, we'll start by creating one collection (table) for each of our main objects.

In restdb.io development mode, we add the three collections by clicking on the Add Collection button. The screenshot below shows the result:

screen shot schema

For this example, we'll also add some random data using the random data generator.

After running the random data generator on each collection, our database now has these populated data collections.

The customers collection:

[
  {
    "_id": "58feea7ebcb53e0d000009ca",
    "customer-name": "Von Group"
  },
  {
    "_id": "58feea7ebcb53e0d000009cb",
    "customer-name": "Tromp Inc"
  }
  ...
]

And the issues collection:

[
  {
    "_id": "58feeab2bcb53e0d000009cc",
    "title": "Printer ink",
    "description": "It's empty in 2. floor. Please fix asap!"
  },
  {
    "_id": "58feeae1bcb53e0d000009d0",
    "title": "Sloow network",
    "description": "Everything just hangs before log in."
  }
  ...
]

And the responsible collection:

[
  {
    "_id": "58feea60bcb53e0d000009b8",
    "name": "Hane.Dante"
  },
  {
    "_id": "58feea60bcb53e0d000009c1",
    "name": "Modesta_Grady"
  },
  ...
]

Creating a Relation With the REST API

Adding relations to objects are done with a REST API call.

In this example, we'll use the PUT verb to add a relation to a customer and a responsible on a specific issue. We do this by providing the ObjectIDs for the particular customer and responsible documents:

PUT /rest/issues/58feeab2bcb53e0d000009cc

{ 
    "title": "Printer ink",
    "description": "It's empty in 2. floor. Please fix asap!",
    "customer": ["58feea7ebcb53e0d000009ca"], 
    "responsible": ["58feea60bcb53e0d000009c1"]
}

After validation the document, the database will produce a result for the modified issue document with an embedded copy of the customer and the responsible documents:

{
    "_id": "58feeab2bcb53e0d000009cc",
    "title": "Printer ink",
    "description": "It's empty in 2. floor. Please fix asap!",
    "customer": [
      {
        "_id": "58feea7ebcb53e0d000009ca",
        "customer-name": "Von Group",
        "_created": "2017-04-25T06:19:42.875Z"
      }
    ],
    "responsible": [
      {
        "_id": "58feea60bcb53e0d000009c1",
        "name": "Modesta_Grady"
        "_created": "2017-04-25T06:19:12.182Z"
      }
    ]
  }

Note that a relation is always represented as an array of objects.

What Happened Here?

For each reference to an object (i.e. relation), the database will keep track of any changes in the original document.

On a change in the original document, i.e. the customer name, the database will also update all copies of that instance — hence keeping data consistency and enabling fast atomic queries.

copy

Who's Looking at Me?

The examples above has shown how issues can have embedded copies (relations) of both customers and responsibles. This is great for speed and consistency.

But how do we find the (implicit) issues that belongs to a specific customer or which issues a specific responsible person has?

Well, since the database keeps track of all relations, it can also tell us where a specific document is used in a relation.

The example queries below shows how you can track the implicit references to a document by using a special query parameter: referencedby=true.

By using this parameter in a query, the database will return the full graph for all other documents that has a relation to the document in the query, i.e. find all issues for the customer 58feea7ebcb53e0d000009ca:

/rest/customers/58feea7ebcb53e0d000009ca?referencedby=true

Result is a full graph of the issues for this customer.

{
  "_id": "58feea7ebcb53e0d000009ca",
  "customer-name": "Von Group"
  "_referencedby": [
    {
      "collection": "issues",
      "references": [
        {
          "_id": "58feeab2bcb53e0d000009cc",
          "title": "Printer ink",
          "description": "It's empty in 2. floor. Please fix asap!",
          "customer": [
            {
              "_id": "58feea7ebcb53e0d000009ca",
              "customer-name": "Von Group",
              "_created": "2017-04-25T06:19:42.875Z"
            }
          ],
          "responsible": [
            {
              "_id": "58feea60bcb53e0d000009c1",
              "name": "Modesta_Grady",
              "email": "Arno.King@gmail.com",
              "_created": "2017-04-25T06:19:12.182Z"
            }
          ],
          "_created": "2017-04-25T06:20:34.441Z",
          "_changed": "2017-04-25T06:20:34.441Z",
          "_version": 0
        },
        {
          "_id": "58feeae1bcb53e0d000009d0",
          "title": "Sloow network",
          "description": "Everything just hangs before log in.",
          "customer": [
            {
              "_id": "58feea7ebcb53e0d000009ca",
              "customer-name": "Von Group",
              "_created": "2017-04-25T06:19:42.875Z"
            }
          ],
          "responsible": [
            {
              "_id": "58feea60bcb53e0d000009c1",
              "name": "Modesta_Grady",
              "email": "Arno.King@gmail.com",
              "_created": "2017-04-25T06:19:12.182Z"
            }
          ],
          "_created": "2017-04-25T06:21:21.390Z",
          "_changed": "2017-04-25T06:21:21.390Z",
          "_version": 0
        }
      ]
    }
  ]
}

Find all issues for a specific responsible. The same format is returned here.

/rest/responsible/58feea60bcb53e0d000009c1?referencedby=true
{
  "_id": "58feea60bcb53e0d000009c1",
  "name": "Modesta_Grady"
  "_referencedby": [
    {
      "collection": "issues",
      "references": [
        ...
      ]
    }
  ]
}

Summary

Objects and relations are a crucial part of any application. By letting the database do the job of maintaining this logic, you will save yourself a ton of work.

At the same time, you will keep the speed and flexibility of a document database, combined with the consistency and integrity of a relational database.

Further reading:

  • Document databases
  • REST API
  • REST API code generator
  • Lookup relations
  • Parent child relations
Relational database Object (computer science) Document application NoSQL Data (computing)

Published at DZone with permission of Jon Erik Solheim, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Introduction to Couchbase for Oracle Developers and Experts: Part 2 - Database Objects
  • Manage Hierarchical Data in MongoDB With Spring
  • Spring Data: Data Auditing Using JaVers and MongoDB
  • The Complete Tutorial on the Top 5 Ways to Query Your Relational Database in JavaScript - Part 2

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!