Fetch Related Records From MongoDB using Mongoose

Fetch Related Records From MongoDB using Mongoose

Post by: Niraj Dhungana

Posted on: Nov 19, 2021

#MongoDB# Mongoose

It doesn't matter whether you are visiting a simple WordPress blog or you are visiting the biggest e-commerce website in the world.

They always try to sell the product or recommend some matching post or product which you are currently opening. Which is called cross selling. So, let’s see how we can do that same exact thing inside MongoDB using mongoose.

Fetch Top 5 Related Blog Posts

Here we will use the example of a blog website and fetch the recent and the matching blog posts according to the user's recent reading. Like here inside this page you can see something called Related Posts on the top left.

To do that first we need to have something inside the post model using which we will find out the current interest of our user. And for that again if you notice at the beginning of the paragraph there are some tags with #tag.

To store tags you can do something like this.

1
2
3
4
const postSchema = mongoose.Schema({
    // other stuff
    tags: [{String}] // now tags will be array of strings
})

They can be tags, keywords or anything suitable with your model.

Now whenever you add a new record store with some related tags.

1
const newPost = new Post({...otherThings, tags: [...myTags]})

Ok once you have some records with matching tags. For example if you have a post related to React JS you can have tags like React, JavaScript. And if you have another post related to React Native with tags React and ReactNative.

In these two posts we will have a common tag React and we will use this common tag to find related posts. So, make sure you are using valid and relatable tags only.

Also you can create a different model where you store tags only. So that you have the information how many tags you already have and use those instead creating new tags everytime.

Magic of MongoDB Aggregation

If you don’t know about aggregation inside mongodb. Then it’s a way where you can add a bunch of tiny little keywords ($operators) provided by MongoDB. And create your own little algorithms to fetch records.

Ok first fetch the post which our reader is requesting for. Because only then we can use the tags from that post and fetch the other related posts.

1
2
3
4
5
const post = await Post.findById(postId);

 const relatedPosts = await Post.find({
      tags: { $in: [...post.tags] }
    })

After getting the post here we are simply using the $in operator and fetching all the posts if they include the tags from the post which the user is requesting for.

You can read more about $in operator here.

If we go with this it will fetch all posts but let's write a logic where we will have only 5 recently uploaded posts. For that we can use the limit and the sort methods from mongoose.

Here we are simply passing the limit of 5 and using this sort method and passing that "-createdAt". So, if we use - in front of createdAt that will fetch new records first. Now we will have only 5 recently uploaded matching posts.

But make user you are storing timestamps inside your MongoDB records. If you don't know then your model should include this code.

1
2
3
4
5
const postSchema = mongoose.Schema({
    // other stuff
    tags: [{String}] // now tags will be array of strings
}, { timestamps: true })

But here we have one more problem. With this logic we will fetch also the post which the current user is reading and this is not a good user experience.

So, let’s exclude the record from this related posts logic. For that we can use another operator from MongoDB called $ne which stands for not equal.

1
2
3
4
5
const relatedPosts = await Post.find({
      tags: { $in: [...post.tags] },
      _id: { $ne: post._id },
    })
    .sort("-createdAt") .limit(5)

Now this is the final logic which will select only 5 related records according to the tags that you pass. Which obviously will be the latest. If there is no related records the result will be empty array [].