How to query distinct values in Mongoose

Updated: December 30, 2023 By: Guest Contributor Post a comment

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.