Sling Academy
Home/Node.js/How to Perform Case-Insensitive Queries in Mongoose

How to Perform Case-Insensitive Queries in Mongoose

Last updated: December 31, 2023

Working with databases often requires flexibility in how queries are performed. In Mongoose, the ODM library for MongoDB in Node.js applications, you can perform case-insensitive queries to enhance the user experience. Understanding how to implement these queries can significantly improve the functionality of your application.

Understanding Mongoose Queries

Before diving into case-insensitive queries, let’s familiarize ourselves with the basics of querying in Mongoose. Mongoose provides a rich API for creating complex queries on MongoDB documents.

const mongoose = require('mongoose');
const { Schema } = mongoose;

const personSchema = new Schema({
  name: String,
  age: Number
});

const Person = mongoose.model('Person', personSchema);

Person.find({ name: 'John Doe' }, function(err, people) {
  if (err) return handleError(err);
  console.log(people);
});

Basic Case-Insensitive Query

To perform a case-insensitive query in Mongoose, you can use regular expressions. Here’s a basic example:

Person.find({ name: new RegExp('^John Doe

This query will match ‘john doe’, ‘John Doe’, ‘JOHN DOE’, or any other case variation.

Using Query Helpers for Case-Insensitive Searches

Mongoose’s query helpers can be used to simplify the creation of case-insensitive queries. Let’s see how to employ them effectively:

personSchema.query.byName = function(name) {
  return this.find({ name: new RegExp(name, 'i') });
};

var query = Person.find().byName('John Doe');
query.exec(function(err, people) {
  if (err) return handleError(err);
  console.log(people);
});

The byName helper is a custom method added to our schema’s query object that allows us to reuse a case-insensitive search for the name field.

Indexing for Performance

When performing case-insensitive queries, it’s essential to consider the impact on performance. Using indexes can help improve query speed. However, normal indexing will not help with case-insensitivity. We need to use a special type of index called a ‘text index’ or manipulate the data:

personSchema.index({ name: 'text' });

Person.find({ $text: { $search: '"John Doe"' } }, function(err, people) {
  if (err) return handleError(err);
  console.log(people);
});

Using a text index will enable case-insensitive and partial matching for queries.

Collation for Case-Insensitive Queries

In MongoDB version 3.4+ (which was released a very long time ago), collation support was added, which brings case-insensitive querying to a new level. With collation, we can execute the queries taking the document’s locale into account:

Person.find()
  .collation({ locale: 'en', strength: 2 })
  .exec(function(err, people) {
    if (err) return handleError(err);
    console.log(people);
  });

The strength: 2 option is what makes the magic for case-insensitivity happen here.

Advanced Case-Insensitive Searching

For more complex scenarios, such as case-insensitive search across multiple fields, Mongoose provides powerful aggregation pipelines:

Person.aggregate([
  { $match: { $text: { $search: '"John Doe"' } } },
  { $sort: { score: { $meta: 'textScore' } } }
]).exec(function(err, people) {
  if (err) return handleError(err);
  console.log(people);
});

This approach yields efficient and flexible case-insensitive searches on larger datasets.

Conclusion

Performing case-insensitive queries in Mongoose is not only feasible but also essential for creating a user-friendly search. Whether utilizing regular expressions, text indexes, or the collation feature, there are several ways to achieve flexible searching within your Mongoose models. Remember to consider performance implications and use indexes whenever possible to ensure efficiency.

Next Article: How to Populate Nested Arrays in Mongoose: A Comprehensive Guide

Previous Article: Mongoose: Find Documents That Contain a Given Value

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