bigscal-logo
  • bigscal-logo
  • Services
    • Software Development
          • Software Product Development
            • SaaS Consulting
            • MVP Development
            • Startup Product Development
            • Product UI/UX Design
            • Startup Consulting
          • Information Technology Consulting
            • Agile Consulting
            • Software Consulting
            • Data Analytics Consulting
            • CRM Consulting
          • Software Outsourcing
            • IT Staff Augmentation
            • Dedicated Development Teams
            • Shadow Engineers
            • Offshore Software Development
            • Offshore Development Center
            • White Label Services
          • Custom Software Development
            • Enterprise Software Development
            • Nearshore Software Development
          • Digital Transformation
    • Application Development
          • Mobile App Development
            • React Native App Development
            • iPhone app development
            • Android App Development
            • Flutter App Development
            • Cross Platform App Development
            • Xamarin App Development
          • Web Development
            • Website & Portal Development
          • Frontend Development
            • Angular Development
            • React.js Development
            • Next.js Development Services
          • Full Stack Development
            • MEAN Stack Development
            • MERN Stack Development
          • Backend Development
            • .NET Development
            • Node js Development
            • Laravel Development
            • PHP Development
            • Python Development
            • Java Development
            • WordPress Development
            • API Development
            • SharePoint Development
          • Cloud Application Development
            • Serverless Software Development
          • Application Maintenance
          • Application Modernization
    • QA & Testing
          • Penetration Testing
          • Usability Testing
          • Integration Testing
          • Security Testing
          • Automated Testing
          • Regression Testing
          • Vulnerability Assessment
          • Functional Testing
          • Software Performance Testing
          • QA Outsourcing
          • Web Application Testing
          • Software Quality Assurance Testers
          • Mobile App Testing
          • QA Consulting
          • Application Testing
    • eCommerce
          • eCommerce Web Design
          • Ecommerce Consulting
          • Digital Consulting
          • eCommerce Web Development
          • Supply Chain Automation
          • B2C eCommerce
          • B2B Ecommerce
    • Analytics & DevOps
          • Big Data Consulting
          • Business Intelligence Consulting
          • Microsoft Power BI
          • Power BI Implementation
          • DevOps Consulting
          • Amazon AWS
          • Microsoft Azure
    • Generative AI Development Services
          • Agentic AI Services
          • AI-ML Developers
          • Hire AI Developers
          • Machine Learning Developers
          • Deep Learning Development
          • IoT Developers
          • Chatbot Developers
  • Industries
    • Education & eLearning
    • Finance
    • Transportation & Logistics
    • Healthcare
      • Hospital Management Software Development
      • Patient Management Software Development
      • Clinic Management System
      • Telemedicine App Development Solutions
      • EMR Software
      • EHR Software
      • Laboratory Information Management Systems
    • Oil and Gas
    • Real Estate
    • Retail & E-commerce
    • Travel & Tourism
    • Media & Entertainment
    • Aviation
  • Hire Developers
    • Mobile Developers
          • Hire Android App Developers
          • Hire iOS App Developers
          • Hire Swift Developers
          • Hire Xamarin Developers
          • Hire React Native Developers
          • Hire Flutter Developers
          • Hire Ionic Developers
          • Hire Kotlin Developers
    • Web Developers
          • Hire .Net Developers
            • Hire ASP.NET Core Developers
          • Hire Java Developers
            • Hire Spring Boot Developers
          • Hire Python Developers
          • Hire Ruby On Rails Developers
          • Hire Php Developers
            • Hire Laravel Developers
            • Hire Codeigniter Developer
            • Hire WordPress Developers
            • Hire Yii Developers
            • Hire Zend Framework Developers
          • Hire Graphql Developers
    • Javascript Developers
          • Hire AngularJs Developers
          • Hire Node JS Developer
          • Hire ReactJS Developer
          • Hire VueJs Developers
    • Full Stack Developers
          • Hire MEAN Stack Developer
          • Hire MERN Stack Developer
    • Blockchain & Others
          • Hire Blockchain Developers
          • Hire Devops Engineers
          • Hire Golang Developers
  • Blogs
  • Careers
  • Company
    • Our Portfolio
    • About Us
    • Contact
  • Inquire Now
  • Menu Menu
Home1 / Backend2 / The Ultimate List of Mongoose Advance Filtration Implementations
Take Charge with Advanced Mongoose Filters

The Ultimate List of Mongoose Advance Filtration Implementations

August 26, 2022/0 Comments/in Backend /by Prathamesh Patil

Quick Summary: The article highlights how to create a Node.js API with Mongoose Advance Filtration and Mongo db pagination, empowering developers to efficiently manage and retrieve data in their applications.

Introduction

Mongoose is one of the most powerful tools for working with MongoDB databases in Node.js applications. Developers must focus on data retrieval when building a simple blog or a complex data-driven application.

If you’re looking for the ultimate list of Mongoose advanced filtration implementations, look no further! This comprehensive list includes everything from simple text filters to more complex image filters. Mongoose advanced Filtration and pagination have a significant role in API design.

A good API design creates a great developer experience (DX). However, there’s no specific standard guideline for API design. RESTful is just an architecture for serving data to front-end applications from web servers.

But to cater to data serving efficiently our APIs need to be efficient to reduce the over-fetching and under-fetching of data. Collaborating with Node.js development services enhances your ability to leverage MongoDB query filters for efficient and customized data handling in web applications.

In this blog, we will understand the MongoDB filter, equipping you with the knowledge and techniques to tackle even the most complex data querying needs.

Also, please read our blog on why Nodejs is better for other languages, which will help you understand this framework’s real-time capabilities.

How to build an API by using filters in Mongodb

Here we are going to build an API with advanced filtration and will set up Node.Js With MongoDB, Express.js, and Mongoose and will be adding in-route validations for API using Joi validations and express-validation.

1. Create a folder with the name adv-filtration or go with your choice of name.
`mkdir adv-filtration`

2. Initiate and project with the command `yarn init –y`

3. Create an src directory where we will write all of our source code.

4. Add following dependencies

Express – For server initialization and routing.
Mongoose – To work with mongo-DB.
Dotenv – To load our environment variable from the .env file.
Joi – for creating validation schema for routes.
Express-validation – To validate in request before it reaches the main controller.

By `yarn add express mongoose dotenv joi express-validation`

5. Add nodemon as dev-dependency `yarn add –D nodemon’
6. Add the following command inside the `package.json` file in the scripts block.

package.json

"scripts": {
                            "start": "node src/index.js",
                            "dev": "nodemon src/index.js"
                            },

7. Now we must create a database schema to work with mongo-DB using mongoose.
Create a new folder by the name `models` inside the src directory and create a file with the name
`product.model.js`.

Add the following code to it.

src/models/product.model.js

const mongoose = require('mongoose');
                            const { Schema } = mongoose;
                            
                            const ProductSchema = new Schema({
                            title : { type: String, required: true },
                            type : { type: String, required: true },
                            description : { type: String, required: true },
                            price : { type: Number, required: true },
                            rating : { type: Number, required: true, max: 5 }
                            }); 
                            
                            module.exports = mongoose.model('product', ProductSchema, 'products');
                            

8. Now we have to create validations for in-route validations for validating the queryString which is responsible for querying the data. And we have to make sure we protect our API from misbehaving because of the wrong conditions in the query.

Note. Whatever we will receive in query will be determining the querying data directly so we have to make our validation as flexible and strong as required.

src/models/product.validation.js

const Joi = require('joi');
                            
                            const numberValidations = [
                            Joi.number().optional(),
                            Joi.object({
                            gt: Joi.number().min(1).optional(),
                            gte: Joi.number().min(1).optional(),
                            lt: Joi.number().min(1).optional(),
                            lte: Joi.number().min(1).optional()
                            }).optional().not({})
                            ]
                            
                            const validTypes = ["bakery", "dairy", "fruit", "meat", "vegan", "vegetable"];
                            
                            exports.getAllProducts = {
                            query: Joi.object({
                            title: Joi.string().optional(),
                            type: Joi.string().valid(...validTypes).optional(),
                            page: Joi.number().min(1).optional(),
                            limit: Joi.number().min(1).optional(),
                            price: numberValidations,
                            rating: numberValidations,
                            sort: Joi.string().optional(),
                            fields: Joi.string().optional()
                            })
                            }

In the above validations, we are making every field optional, but if they are provided we need to make sure to validate them, like `numberValidation` here we are supposed to expect a single number of an object having fields [ gt, gte, lt, lte ] only. Type should be one of [“bakery”, “dairy”, “fruit”, “meat”, “vegan”, “vegetable”] etc.

9. Now we will create our controller in the src directory with the name product.controller.js which is responsible for serving our data. Our controller will be flexible enough to fetch data from the database with given conditions in query, sort records according to the given field and more than one field and orders of given fields in a query, paginate it, and limit the number of fields requested by the client.

src/controllers/product.controller.js
                            
                            const getAllProducts = async (req, res, next) => {
                            try {
                            
                            let queryObject = { ...req.query };
                            
                            /* Basic Filtration */
                            const excludeFields = ['page', 'sort', 'limit', 'fields'];
                            excludeFields.forEach(item => delete queryObject[item]);
                            
                            /* Advance Filtering */
                            let queryString = JSON.stringify(queryObject);
                            queryString = queryString.replace(/\b(gte|gt|lte|lt)\b/g, match => `$${match}`);
                            queryObject = JSON.parse(queryString);
                            
                            /* Search on the basis of title of product */
                            if(queryObject.title) {
                            queryObject.title = new RegExp(queryObject.title, 'i');
                            }
                            
                            let query = Product.find({ ...queryObject });
                            const countQuery = Product.find({ ...queryObject });
                            
                            /* Sorting */
                            if(req.query.sort) {
                            const sortBy = req.query.sort.split(',').join(' ');
                            query = query.sort(sortBy);
                            } else {
                            query = query.sort({ createdAt: - 1 })
                            }
                            
                            /* Limiting the field ( projection ) */
                            if (req.query.fields) {
                            const fields = req.query.fields.split(',').join(' ');
                            query = query.select(fields);
                            } else {
                            query = query.select('-__v');
                            }
                            
                            /* Pagination */
                            const page = req.query.page * 1 || 1;
                            const limit = req.query.limit * 1 || 10;
                            const skip = (page - 1) * limit;
                            
                            const totalRecords = await countQuery.countDocuments();
                            
                            query = query.skip(skip).limit(limit);
                            
                            let numOfRecords = 0;
                            if (req.query.page) {
                            numOfRecords = await Product.countDocuments({ ...queryObject });
                            if (skip > numOfRecords) {
                            return res.status(404).json({ status: false, message: 'Page does not exists!' });
                            }
                            }
                            
                            let products = await query;
                            return res.status(200).json({
                            status: true,
                            data: {
                            products,
                            totalPages: Math.ceil(totalRecords / limit),
                            page,
                            limit,
                            totalRecords
                            }
                            });
                            } catch (error) {
                            next(error)
                            }
                            }

In the above controller, we will be having the below flow.
a) Copy everything from req. query to queryObject using spread operator so modification in queryObject doesn’t affect the req. query;
b) Basic Filtration
c) Remove these [‘page’,’sort’,’limit’,’fields’] from queryObject.
d) Advance Filtration
e) Convert our queryObject to JSON string using JSON.stringify to queryString and use regex to replace exact gt/gte/lt/lte words with $ prepend with it so they can act as MongoDB operators.
i) e.g gt to $gt, lt to $lt.
ii) and parse back that queryString to queryObject again using JSON.parse()
g) If we are given the facility to search products by titles. Then convert that title string to regex to search globally and case-insensitively.
Till now we have created the condition of our query now we will create a query so we can perform additional operations on it for reference of query you can read it here: https://mongoosejs.com/docs/queries.html

Along with that, we will fire a query with the same query object in order to get the total count of records with the given filtration.

h) Now it’s time to sort. If we have got a sort request in the req. the query then we will split the sort value and join them to create a comma-separated string having fields separated by a comma. And will use the query.sort() method and pass that string to it.
What if we didn’t receive a sort request we will sort the record by its creation date by default.

i) Now it’s time to limit the number of fields to be sent in response, If we have got fields in the req. the query then we will split and fields value and join them to create a comma, separated string and will use query.select() method and pass that string to it. So the mentioned fields are only the object we will be getting from the response.
a) What if we didn’t receive the fields in request them we will remove the __v field by default.

b) Note: To remove field use – before that field and that field will be removed from response.
c) Or mention those fields only those fields which you expect from the response.

j) Now its turns for pagination
If page and limit are not provided in req. the query then by default the page will be 1 having a limit of 10 records per page.
For the custom pages, you can pass pages and limit values in the request.

k) Then comes the last condition to check if the page is requested is present or not.
If not then we have to throw an error with an appropriate message.

l) Till now we have built our query with all features, it’s time to fire that query now, we will execute that query and will send a response with that data and pagination-related data like currentPage, limit, total pages, and total records available.

m) Send the gathered data.

10) Now create the route for the product inside the routes directory with name product.route.js
And add the following code to it.

const router = require('express').Router();
                            const { validate } = require('express-validation');
                            const { getAllProducts } = require("../validations/product.validation");
                            const ProductController = require('../controllers/product.controller');
                            
                            router.get('/', (req, res, next) => res.redirect('/products'));
                            router.use('/products', validate(getAllProducts), ProductController.getAllProducts);
                            
                            module.exports = router;

Note: Here we have added the in-route validation of query using the assurance we have created using joi and validating it using validate function imported from express-validation.

11) Create the .env file on the root level of the project and add the following code to it.

PORT=4000
DB_URI=mongodb://localhost:27017/test-DB

12) Now final thing to do add create an index.js file inside the src directory and add the below code.

require('dotenv').config();
                            const express = require('express');
                            const { ValidationError } = require('express-validation');
                            const mongoose = require('mongoose');
                            const indexRouter = require('./routes/product.route');
                            const port = process.env.PORT || 4000;
                            const app = express();
                            
                            app.use(indexRouter);
                            
                            app.use((req, res, next) => {
                            const err = new Error('Resource not found');
                            err.status(404);
                            next(err);
                            });
                            
                            app.use((err, req, res, next) => {
                            let status;
                            let message;
                            if (err instanceof ValidationError) {
                            status = 422;
                            message = err.details.query[0].message;
                            } else {
                            status = err.status || 500;
                            message = err.message || 'Something went wrong.';
                            }
                            return res.status(status).json({ status: false, message });
                            })
                            
                            mongoose.connect(process.env.DB_URI).then(() => {
                            console.log("Database is Connected.");
                            app.listen(4000, () => console.log(`Server is up 🚀 and running at ${port}`));
                            });

We have done with our server part now you can call our API with filtration.
e.g

server part

Implementing Advance Filtration and Pagination in node with mongoose

e.g

With the help of the price and rating fields and the gt, gte, lt, and lte operators, you may filter records by title, price, rating, and type.

You can limit the fileds by passing fields in the query with required field values.
You can pass pagination info to get data page by page.

Implementing Advance Filtration and Pagination in node with mongoose.

e.g 2

passing fields in the query

Implementing Advance Filtration and Pagination in node with mongoose1

Conclusion

Mongoose advanced filtration helps developers to streamline the Node.js development process. Read this article to get valuable insights for building powerful APIs.

FAQ

What is mongoose paginate?

Python-paginate-v2 implements a page wrapper for pagination. You can directly modify the return value keys in the query itself with the plugin, so you don’t have to write extra code for transformation.

How to apply pagination in Mongoose?

Mongoose uses this method to paginate. SQL queries are used here to paginate the data from the database using limit and offset. NoSQL databases will be limited and skipped if you work on them. Page and limit are two parameters the client must supply in the request.

How to implement pagination in REST API MongoDB?

The pageNumber variable in the request query object is converted to an integer before being sent to the client. Similarly, we return to the client the size of data requested by the client by converting the limit variable from the client’s request query object to an integer.

.What is __ V in MongoDB?

Revisions are tracked in this v field. The value of this variable is zero by default. The v field only increases by one when an array is updated. The value of __v remains unchanged in other situations.

What is the benefit of Mongoose in MongoDB?

Mongoose provides a schema for our application code to work against and a direct relationship between our MongoDB documents and the Mongoose models. As a result, we can only create blog posts that comply with the above-described schema.

Tags: #bigscal, #bigscaltechnologies, #hire nodejs developer, #Js, #mongodb, #node, #node developer, #node.js, #node.js developers, #nodejs development, javascript, Mongoose

You might also like

Cracking the Code: Cyber Security Explained What is a Cyber Security?
React Hook Form vs Others: Who Wins? Why is React Hook Form better than other forms?
Master Redis: Learn Commands, Discover Use Cases What is Redis?
Discover the top 13 React tools Software Developers absolutely need to know Top 13 React Tools That Every Software Developer Should Know
Discover the Impact of Google's BARD on AI Search Google’s BARD and Its Impact on the AI-Powered Search Industry
Explore DataTables: Client VS Server-side DataTables – Client-side Processing VS Server-side Processing

Seeking robust and scalable software solutions?

Contact us for industry-leading development services.

Book a 30 min FREE Call

Craft your Best Agile Team

Your Project, Our Expertise - Hire a Developer Now

    Subscribe for
    weekly updates

      privacy-policy I accept the terms and conditions

      Categories

      • AI-ML-Blockchain
      • Aviation
      • Backend
      • Cloud
      • Cross Platform
      • Cyber Security
      • Database
      • DevOps
      • Digital Marketing
      • Ecommerce
      • Education Industry
      • Entertainment Industry
      • Fintech Industries
      • Frontend
      • Full Stack
      • Game Development
      • Healthcare Industry
      • Latest Technology News
      • Logistics Industry
      • Mobile app development
      • Oil And Gas Industry
      • Plugins and Extensions
      • QA & Testing
      • Real Estate Industry
      • SaaS
      • Software Development
      • Top and best Company
      • Travel industries
      • UI UX
      • Website Development

      Table of Content

      bigscal-technology
      india
      1st Floor, B - Millenium Point,
      Opp. Gabani Kidney Hospital,
      Lal Darwaja Station Rd,
      Surat – 395003, Gujarat, INDIA.
      us
      1915, 447 Broadway,
      2nd Floor, New York,
      US, 10013
      +91 7862861254
      [email protected]

      • About
      • Career
      • Blog
      • Terms & Conditions
      • Privacy Policy
      • Sitemap
      • Contact Us
      Google reviews
      DMCA.com Protection Status
      GoodFirms Badge
      clutch-widget
      © Copyright - Bigscal - Software Development Company
      Google reviews
      DMCA.com Protection Status
      GoodFirms Badge
      clutch-widget

      Stay With Us

      Are you looking for the perfect partner for your next software project?

      Google reviews GoodFirms Badge clutch-widget
      • IP Rights, Security & NDA. Full ownership and confidentiality with robust security guaranteed.
      • Flexible Contracts & Transparency. Tailored contracts with clear and flexible processes.
      • Free Trial & Quick Setup. No-risk trial and swift onboarding process.

        Introducing Airbrake With Node Js Explained Airbrake Takes Node.js to New Heights! Base64 Image Download in React Native: Simplified! How do you download base64 images in React Native?
        Scroll to top

        We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it.

        AcceptHide notification onlySettings

        Cookie and Privacy Settings



        How we use cookies

        We may request cookies to be set on your device. We use cookies to let us know when you visit our websites, how you interact with us, to enrich your user experience, and to customize your relationship with our website.

        Click on the different category headings to find out more. You can also change some of your preferences. Note that blocking some types of cookies may impact your experience on our websites and the services we are able to offer.

        Essential Website Cookies

        These cookies are strictly necessary to provide you with services available through our website and to use some of its features.

        Because these cookies are strictly necessary to deliver the website, refuseing them will have impact how our site functions. You always can block or delete cookies by changing your browser settings and force blocking all cookies on this website. But this will always prompt you to accept/refuse cookies when revisiting our site.

        We fully respect if you want to refuse cookies but to avoid asking you again and again kindly allow us to store a cookie for that. You are free to opt out any time or opt in for other cookies to get a better experience. If you refuse cookies we will remove all set cookies in our domain.

        We provide you with a list of stored cookies on your computer in our domain so you can check what we stored. Due to security reasons we are not able to show or modify cookies from other domains. You can check these in your browser security settings.

        Other external services

        We also use different external services like Google Webfonts, Google Maps, and external Video providers. Since these providers may collect personal data like your IP address we allow you to block them here. Please be aware that this might heavily reduce the functionality and appearance of our site. Changes will take effect once you reload the page.

        Google Webfont Settings:

        Google Map Settings:

        Google reCaptcha Settings:

        Vimeo and Youtube video embeds:

        Privacy Policy

        You can read about our cookies and privacy settings in detail on our Privacy Policy Page.

        Privacy Policy
        Accept settingsHide notification only