Sling Academy
Home/Node.js/Mongoose: Find Documents That Contain a Given Value

Mongoose: Find Documents That Contain a Given Value

Last updated: December 30, 2023

Introduction

When working with Mongoose, a data modeling library for MongoDB and Node.js, developers often need to retrieve documents based on certain criteria. One common task is to find documents where a particular field contains a specific value. This tutorial will walk you through various ways to achieve this, using the latest ES6+ syntax and async/await patterns for clean and readable code.

We’ll start with basic queries using find, and gradually move on to more sophisticated queries, including those employing regular expressions and array search. By the end of this tutorial, you should feel confident in retrieving documents to fit a wide range of use cases.

Let’s get started by setting up Mongoose and the model we’ll be using for our examples.

Getting Started

Ensure you have Node.js installed, then set up a new project and install mongoose:

npm init -y
npm install mongoose

Create a file named db.js and establish a connection to MongoDB:

import mongoose from 'mongoose';
mongoose.connect('mongodb://localhost/database_name', {useNewUrlParser: true, useUnifiedTopology: true});

Define a schema and model for our examples. In this case, let’s create one for blog posts:

import { Schema, model } from 'mongoose';

const blogPostSchema = new Schema({
  title: String,
  content: String,
  tags: [String],
  publishedDate: Date
});

const BlogPost = model('BlogPost', blogPostSchema);

With the initial setup complete, we can begin exploring various find operations.

Basic Queries

The most straightforward use case is finding documents where a field exactly matches a given value. In Mongoose, this is achieved using the find method:

async function findPostsByTitle(title) {
  try {
    const results = await BlogPost.find({ title: title });
    return results;
  } catch (error) {
    console.error('Error finding posts:', error);
  }
}

// Use the function
findPostsByTitle('Node.js Basics').then(console.log);

ES6+ provides syntactic sugar for properties where the key and value are the same, allowing us to simplify the query:

const results = await BlogPost.find({ title });

To find documents containing a given substring in a text field, you can use regular expressions:

async function findPostsContainingText(text) {
  try {
    const regex = new RegExp(text, 'i'); // The 'i' flag makes it case-insensitive
    const results = await BlogPost.find({ content: { $regex: regex } });
    return results;
  } catch (error) {
    console.error('Error finding posts with text:', error);
  }
}

// Usage
findPostsContainingText('mongoose').then(console.log);

Searching Within Arrays

The $in operator allows querying multiple values within an array field:

async function findPostsByTags(tagsArray) {
  try {
    const results = await BlogPost.find({ tags: { $in: tagsArray } });
    return results;
  } catch (error) {
    console.error('Error finding posts by tags:', error);
  }
}

// Using the functionindPostsByTags(['tutorial', 'JavaScript']).then(console.log);

Advanced Query Techniques

If we want to combine criteria, the logical operators $and and $or are extremely helpful:

async function findPublishedAfterDateWithTags(date, tagsArray) {
  try {
    const results = await BlogPost.find({
      publishedDate: { $gte: date },
      tags: { $in: tagsArray }
    });
    return results;
  } catch (error) {
    console.error('Error finding posts:', error);
  }
}

// Use the function
findPublishedAfterDateWithTags(new Date('2021-01-01'), ['news']).then(console.log);

An example of complex searching criteria, can be attained by pushing to the next level using projection, sorting, and pagination:

async function findAndSort(tagsArray, skip, limit) {
  try {
    const results = await BlogPost.find({text: {$regex: /matchtext/i})
      .select('title publishedDate') // Projection
      .sort({ publishedDate: -1 }) // Sorting
      .skip(skip) // Pagination
      .limit(limit);
    return results;
  } catch (error) {
    console.error('Error finding and sorting posts:', error);
  }
}

// Example usage:
findAndSort(['tutorial'], 0, 10).then(console.log);

Conclusion

In this tutorial, we covered the basics of finding documents in Mongoose where a field contains a specific value using different approaches. Remember, efficient database querying not only involves knowing various query techniques but also includes understanding how to harness the capabilities of indexing and MongoDB’s powerful aggregation framework for optimal performance.

Take the time to explore the Mongoose API further, and experiment with creating more complex queries tailored to your data needs. With this knowledge in your toolkit, Mongoose will serve as an even more powerful ally in your Node.js development endeavors.

Next Article: How to Perform Case-Insensitive Queries in Mongoose

Previous Article: Mongoose: 3 Ways to Remove All Documents from a 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