DEV Community

Cover image for Learn MongoDB: Working with Indexes
Paras 🧙‍♂️
Paras 🧙‍♂️

Posted on

Learn MongoDB: Working with Indexes

In mongodb, we can create indexes on fields so that when we query data using that field, we can get results instantly. It is like accessing a value from an array using index. Without index, we have to look for the data in linear way, which is not optimal in large datasets. So, we will learn about indexes in this post.

Let's begin !!


Table of Content


What is indexing ?

Indexing is a way to optimize the performance of accessing data from database. It allows us to efficiently fetch data from our database without having to traverse it as a whole. You can think of it like arrays or maps where we use index or key to get our data without having to search for it in a linear way.

How indexing works ?

Indexing, in background, keeps a table of key-value pair i.e. a table with two columns. First column has the key, which is actually the value that we want to search for in the table. For example: if we create an index on name field, then first column will have all the names in the database. While the second column keeps track of the pointers to the actual data. With the help of pointers, we fetch the actual data from our database.

Search Key Database References (Values)
Arthur reference_key_1
Ash reference_key_2
John reference_key_3

One good property of index table is keeping search keys in sorted order. In our case, search keys are stored in alphabetical order. This helps us find data much quickly (if you know binary search, then you know why sorting is helpful).

Also, if you are confused about what are these reference keys, then in this example we can say that these are the primary keys (in mongodb "_id" keys). They refer to the user in our database. These keys are already indexed, and data can be retrieved quickly using these "id" keys.

Working with Indexes

For working with indexes, we have a few cool methods:

  • createIndex
  • dropIndex
  • getIndexes
  • explain (to check how your queries are performing)

Before starting let's see a simple schema based on pokemon trainers. We will add fields according to our needs.

{
   name: "Ash",
   age: 18,
   pokemons: [
      { name: "pikachu", type: "electric", level: 16 },
      { name: "charizard", type: "fire", level: 30 },
      { name: "squirtle", type: "water", level: 12 }
   ],
   badges: ["boulder badge", "cascade badge"],
   exp: 200,
   bagItems: {
      pokeballs: 8,
      heals: 10
   },
}
Enter fullscreen mode Exit fullscreen mode

Creating Index

Let's create an index on name field:

> db.trainers.createIndex({age: 1}) // 1 ascending & -1 descending

// index a nested field
> db.trainers.createIndex({"bagItems.pokeballs": 1})
Enter fullscreen mode Exit fullscreen mode

Get Indexes

> db.trainers.getIndexes()

// _id is the default index
Enter fullscreen mode Exit fullscreen mode

Check your index

We will use explain method to check if our queries are using the index or not.

> db.trainers.find({age: 18}).explain()

// a bit more specific
> db.trainers.find({age: 18}).explain("allPlansExecution")
Enter fullscreen mode Exit fullscreen mode

If you apply the explain method, you will get a big object with so many details, which can be overwhelming. But we will focus on main fields.

Main fields are:

  • inputStage: In this key, our main field is winningPlan. It can be COLLSCAN (Full Collection Scan) or IXSCAN (Index Scan)
  • executionTimeMillis: It shows the time taken by your query to get the data. This is important because we will use this field to compare different indexes and queries execution time.
  • totalDocsExamined: This field shows how many docs mongo has to check before returning results. The lower the number, the better.

You can see there is input stage in explain result. This is first stage where mongo gets the keys and pointers from index table and then use those pointers to fetch actual docs.

Drop Index

Deleting index is also very easy. Just specify the object with that index.

// let's drop our age index
> db.trainers.dropIndex({age: 1})

// you can also specify index "name" that you can get from "getIndexes" method
> db.trainers.dropIndex("age_1")
Enter fullscreen mode Exit fullscreen mode

You should know that these are just the basics. We have a lot to cover like text index, compound index, multi-key index, more about execution and plan rejection, etc. etc. So, we learn these things in next post !

Next Post : Coming soon...!!

Prev Post : Delete Documents

Top comments (0)