Sling Academy
Home/Node.js/How to query distinct values in Mongoose

How to query distinct values in Mongoose

Last updated: December 30, 2023

Introduction

Mongoose is a powerful Object Data Modeling (ODM) library for MongoDB and Node.js. It helps to manage relationships between data, provides schema validation, and is used to translate between objects in code and their representation in MongoDB. In this tutorial, we’ll explore how to leverage Mongoose to query for distinct values within a collection—a common need when looking to find unique instances of data among duplicate entries.

To follow along, ensure you have the latest version of Node.js installed and an understanding of modern JavaScript syntax, including ES modules, arrow functions, and async/await.

Setting Up Your Project

Begin by setting up a new Node.js project and install Mongoose:

mkdir mongoose-distinct-tutorial
cd mongoose-distinct-tutorial
npm init -y
npm install mongoose

Once installed, connect to your MongoDB database:

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/mydatabase', { useNewUrlParser: true, useUnifiedTopology: true });

Defining a Schema and Model

Before querying, we need to define a schema and a corresponding model:

const { Schema, model } = require('mongoose');
const ItemSchema = new Schema({
  category: String,
  name: String
});
const Item = model('Item', ItemSchema);

Basic Distinct Query

To query for distinct values, use the distinct() function on your model:

Item.distinct('category', (error, result) => {
  if (error) throw error;
  console.log(result); // array of distinct categories
});

You can also use async/await for a cleaner syntax:

const getDistinctCategories = async () => {
  try {
    const distinctCategories = await Item.distinct('category');
    console.log(distinctCategories);
  } catch (error) {
    console.error(error);
  }
};
getDistinctCategories();

Query with Conditions

Sometimes you might want to find distinct values that match certain criteria:

const getItemsInSpecificCategory = async (categoryName) => {
  try {
    const distinctItems = await Item.distinct('name', { category: categoryName });
    console.log(distinctItems);
  } catch (error) {
    console.error(error);
  }
};
getItemsInSpecificCategory('Electronics');

Using Aggregation for Advance Distinct Queries

The aggregation framework offers more power and flexibility, allowing you to chain several operations:

const getAdvancedDistinctData = async () => {
  try {
    const results = await Item.aggregate([
      { $match: { category: 'Electronics' } },
      { $group: { _id: '$name', totalPrice: { $sum: '$price' } } },
      { $sort: { totalPrice: -1 } }
    ]);
    results.forEach(result => {
      console.log(`Item: ${result._id}, Total Price: ${result.totalPrice}`);
    });
  } catch (error) {
    console.error(error);
  }
};
getAdvancedDistinctData();

Performance Considerations

In the context of performance, the distinct operation is relatively quick as MongoDB maintains internal structures to assist with these types of queries. However, like any database operation, the performance can degrade with very large datasets or complex aggregation pipelines. Always index fields being queried on whenever possible.

Conclusion

This tutorial introduced basic to advanced ways to query for distinct values in a MongoDB database using Mongoose in a Node.js application. We covered setting up a project, creating models, querying for distinct values simply, querying with conditions, and harnessing the aggregation framework. Practice these methods to hone your skills and make your application data handling more efficient and powerful.

Note: The code examples in this tutorial are written in CommonJS syntax; make sure to adapt them accordingly if you’re using ES modules.

Next Article: Mongoose: How to sort results by multiple fields

Previous Article: Mongoose: How to Access a Pre-Existing Collection

Series: Mongoose.js Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates