MongoDB Full Text Search Tutorial

In this tutorial, we are going to explore how to setup MongoDB for full text search using Node.js and Mongoose. Using Mongoose is completely optional as the full text search is a native feature ofMongoDB. Make sure your software up to date with the following versions:

  • Node 8.6.0
  • MongoDB 3.4.9
  • Mongoose 4.13.5 (Optional)

What is Full Text Search?

Full text search is the ability to efficiently search strings within strings like finding a keyword in a large text. Usually, database management systems create a special index for this. Basically, all words in a string are indexed, so that they can be found without needing to scan the entire string for matches. This is particularly effective for long texts or for large collections.

Also, database management systems apply various optimizations by default like removing stop words like athe, orand the some even take into account similar words and typos.

Advantages of MongoDB Full Text Search

MongoDB text indexes are easy to setup and use and the performance is relatively good. It has a few cool options like searching for a keyword while discarding another. This is a nice feature to have out-of-the-box and it will suffice for most simple applications.

Disadvantages of MongoDB Full Text Search

As of the time of this writing, it is not possible to do ‘fuzzy’ search, meaning to do partial matching. For instance, searching ana will match ana, Ana, or even aña, but it will not match anaconda or anabelle . The only way to get this to work is with regular expressions, but that’s a poor solution for medium to large data sets.

MongoDB does not provide partial word matching. Only whole words can be searched.

Setting up the Mongoose schema

In this example, we are going to use a products collection. The goal at the end of this tutorial is to be able to search products by name or description.

const mongoose = require('mongoose');

const { ObjectId } = mongoose.Schema.Types;

const productSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    minlength: 3,
    trim: true,
  description: {
    type: String,
    trim: true,
  price: {
    type: Number,
    required: true,
    min: 0,

Setting up the Text Index

This is the important part. We will add a text index. Note that you can add as many fields as you want, but there can only be a single text index per collection. We will add the name and description fields.

  name: 'text',
  description: 'text',
}, {
  weights: {
    name: 5,
    description: 1,

Optionally, you may add weights to the fields. In this case, name will have a higher matching score than description.

To add all string fields to the text index you can use productSchema.index({ '$**': 'text' })

Finally, export the model as usual by doing:

const Product = mongoose.model('Product', productSchema);

module.exports = Product;

Searching using a keyword

Finally, you simply perform a regular find query, but in addition to the fields you usually would filter with, you now can add the $search option. It will return all documents that match any of the given terms.

const term = 'apple';

  $text: { $search: term },
  .then(products => console.log(products))
  .catch(e => console.error(e));

That’s all you need to perform basic text search efficiently in MongoDB and Mongoose!

Additional Indexing Options

There are many other things that can be configured to improve the search results relevance and speed. When creating the index you can tweak the weight, case and symbol sensitivity, and even language. Find all the indexing options in the official indexing documentation.

Additional Query Options

At the time of searching, you may tweak the query to get the most relevant results. Some of the options include:

      $search: <string>,
      $language: <string>,
      $caseSensitive: <boolean>,
      $diacriticSensitive: <boolean>

For a full list of query options read the official text query documentation.

Final thoughts

MongoDB provides an excellent tool for full text search that is easy-to-use and convenient. Unfortunately, it is not very intelligent and has limited options.

For advanced searches using partial words, synonyms and typos you would need to use third-party solutions like Elastic Search, Solr or Algolia.

  • Elasticsearch is open source, but it seems a little cumbersome to set up. Also, you need to connect MongoDB to it as a replica.
  • Amazon Elasticsearch is the same thing, but it is much easier to setup, deploy and scale. You still need to configure MongoDB to replicate towards the Elasticsearch instances. The cost of the instances is similar to those of EC2.
  • Algolia this is my favorite solution so far and the one I use. It’s a very powerful engine that is completely managed, so you don’t have to worry about installations or scalability. It’s extremely easy to use, the control panel is superb, and it has packages and code examples for every major programming language.

Share Post :


Leave a Reply