Sling Academy
Home/Node.js/Mongoose: Search documents by a given field/property value

Mongoose: Search documents by a given field/property value

Last updated: December 30, 2023

Introduction

Mongoose is a powerful Object Data Modeling (ODM) library for MongoDB and Node.js. It provides a straightforward, schema-based solution to model your application data. One of the most common tasks when working with databases is searching for documents based on given field or property values. In this tutorial, you’ll learn how to effectively search and filter documents in a MongoDB database using Mongoose, embracing modern JavaScript syntax and best practices such as arrow functions, async/await, and ES modules.

First, ensure you have Mongoose installed and a MongoDB server running. Set up a Mongoose schema and model for the documents you’ll be searching. Here’s an example using a simple User model:

import mongoose from 'mongoose';
const userSchema = new mongoose.Schema({
  name: String,
  age: Number,
  email: String
});
const User = mongoose.model('User', userSchema);

Now, let’s execute a basic search for documents with a specific name:

const findUsersByName = async (name) => {
  try {
    const users = await User.find({ name: name });
    console.log(users);
  } catch (error) {
    console.error('Error finding users:', error);
  }
};

Searching with Query Operators

Mongoose supports MongoDB’s rich query operators, allowing you to perform more complex searches. If you wanted to find users within a certain age range, you could use the `$gte` (greater than or equal to) and `$lte` (less than or equal to) operators to define your query conditions:

const findUsersInAgeRange = async (minAge, maxAge) => {
  try {
    const users = await User.find({ age: { $gte: minAge, $lte: maxAge } });
    console.log(users);
  } catch (error) {
    console.error('Error finding users:', error);
  }
};

For scenarios where a full-text search is needed, Mongoose can utilize MongoDB’s text search capabilities. To do this, first define a text index on the fields you want to search:

userSchema.index({ name: 'text', email: 'text' });
// Create the index in MongoDB
User.createIndexes();

Then perform text searches using the `$text` operator and the `$search` option:

const searchText = 'John Doe';
const searchUsersByText = async (text) => {
  try {
    const users = await User.find({ $text: { $search: text } });
    console.log(users);
  } catch (error) {
    console.error('Error in text search:', error);
  }
};

Advanced Querying: Using Aggregations

Aggregation queries are useful for more complex data processing tasks. For instance, you can combine data from different documents or compute various metrics based on specific conditions:

const userAgeStats = async () => {
  try {
    const stats = await User.aggregate([
      { $match: {} },
      { $group: { _id: null, avgAge: { $avg: '$age' }, maxAge: { $max: '$age' } } }
    ]);
    console.log(stats);
  } catch (error) {
    console.error('Error aggregating user data:', error);
  }
};

Indexing for Performance

When working with large datasets, indexing becomes critical for search performance. Ensure you have appropriate indexes set up for fields that are frequently searched. For example:

User.createIndexes({ email: 1 });

Conclusion

Through this tutorial, we’ve covered basic and advanced searching techniques using Mongoose. Modern JavaScript syntax and the power of async/await have helped us keep our code clean and readable. While we’ve focused on functionalities provided by Mongoose and MongoDB, consider the specific needs of your application and optimize your approach accordingly for efficiency, especially when dealing with large datasets or complex search requirements.

Next Article: Mongoose: Find documents since last day, last week, last month

Previous Article: Mongoose: Find Documents Between Two Dates (Inclusive)

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