Mongo DB Compound Index Creation Guide:

Indexes

Indexes support the efficient execution of queries in MongoDB. Without indexes, MongoDB must perform a collection scan, i.e. scan every document in a collection, to select those documents that match the query statement. If an appropriate index exists for a query, MongoDB can use the index to limit the number of documents it must inspect.

Creating an Index for a Collection

Assuming you have inserted some data in your collection and you want to assign a field to be an index, you can use the createIndex method to achieve this, i.e.

Let’s say you have this json data:

12345{    _id:1,    Name: “Sepp Maier”,     Country: “Germany”}

We can make the Name field a descending index by:

1db.collection.createIndex({Name: -1})

This method creates an index with the same specification if only not in existence already.

Types of Indexes in MongoDB

  1. Single FieldUsing a single field of a document one can make the field an index in an ascending or descending manner just like the example above. Besides, you can create an index on an embedded document as a whole, for example
  2. Contact field is an embedded document hence we can make it an ascending index with the command:

{     _id: “xyz”,    Contact:{        email: “example@gmail.com”,         phone:”+420 78342823” },    Name: “Sergio”}

  1. 1db.collection.createIndex({ Contact: 1})In a query we can fetch the document like:
  2. db.collection.find({     Contact: {email: “example@gmail.com”,    phone:”+420 78342823”} })A best practice is creating the index in the background especially when a large amount of data is involved since the application needs to access the data while building the index.
  3. Compound Index: Compound indexes are often used to facilitate the sort operation within a query and support queries that match on multiple fields. The syntax for creating a compound index is:1db.collection.createIndex( { <field0>: <type>, <field1>: <type1>, ... } )Creating a compound index for the sample data below1234567{     _id: “1”,    Name: “Tom”,    Age: 24,    Score:”80”}db.collection.createIndex({ Age: 1, Score:-1})
  4. Considerations:
    • A limit of only 32 fields can be supported.
    • Value of the field will define the type of index i.e. 1 is ascending and -1 is descending.
    • Don’t create compound indexes that have hashed index type.
    • The order of fields listed in a compound index is important. The sorting will be done in accordance with the order of the fields.
  5. Multikey IndexAt some point, you may have fields with stored array content. When these fields are indexed, separate index entries for every element are created. It therefore helps a query to select documents that consist arrays by matching on element or elements of the arrays. This is done automatically by MongoDB hence no need for one to explicitly specify the multikey type. From version 3.4, MongoDB tracks which indexed fields cause an index to be a multikey index. With this tracking, the database query engine is allowed to use tighter index bounds.Limitations of Multikey Index
    • Only one array field can be used in the multikey indexing for a document in the collection. I.e. You cannot create a multikey index for the command and data below1

MongoDB involves different types of data hence different types of indexes are derived to support these data types and queries.

  • Only one array field can be used in the multikey indexing for a document in the collection. I.e. You cannot create a multikey index for the command and data below1{ _id: 1, nums: [ 1, 2 ], scores: [ 30, 60 ]}You cannot create a multikey index1{ nums: 1, scores: 1 }
  • If the multikey index already exists, you cannot insert a document that violates this restriction. This is to say if we have12{ _id: 1, nums:  1, scores: [ 30, 60 ]}{ _id: 1, nums: [ 1, 2 ], scores:  30}After creating a compound multikey index, an attempt to insert a document where both nums and scores fields are arrays, the database will fail the insert.
  • After creating a compound multikey index, an attempt to insert a document where both nums and scores fields are arrays, the database will fail the insert.

Overall Operational Considerations for Indexes

  • Each index requires at least 8kB of data space.
  • When active, each index will consume some disk space and memory. This is significant when tracked in capacity planning.
  • For a high read-to-write ratio collection, additional indexes improve performance and do not affect un-indexed read operations.

Limitations of Using Indexes

  • Adding an index has some negative performance impact for write operations especially for collections with the high write-to-read ratio. Indexes will be expensive in that each insert must also update any index.
  • MongoDB will not create, update an index or insert into an indexed collection if the index entry for an existing document exceeds the index key limit.
  • For existing sharded collections, chunk migration will fail if the chunk has a document that contains an indexed field that has an index entry that exceeds the index key limit.

Conclusion

There are so many ways of improving MongoDB performance, indexing being one of them. Indexing facilitates query operations by reducing latency over which data is retrieved by somehow minimizing the number of documents that need to be scanned. However, there are some considerations one needs to undertake before deciding to use a specific type of index. Collections with high read-to-write ratio tend to utilize indexes better than collections with high write-to-read operations.

How does the order of compound indexes matter in MongoDB performance-wise?

Redsandro,

You must consider Index Cardinality and Selectivity.


1. Index Cardinality

The index cardinality refers to how many possible values there are for a field. The field sex only has two possible values. It has a very low cardinality. Other fields such as names, usernames, phone numbers, emails, etc. will have a more unique value for every document in the collection, which is considered high cardinality.

  • Greater CardinalityThe greater the cardinality of a field the more helpful an index will be, because indexes narrow the search space, making it a much smaller set.If you have an index on sex and you are looking for men named John. You would only narrow down the result space by approximately %50 if you indexed by sex first. Conversely if you indexed by name, you would immediately narrow down the result set to a minute fraction of users named John, then you would refer to those documents to check the gender.
  • Rule of ThumbTry to create indexes on high-cardinality keys or put high-cardinality keys first in the compound index. You can read more about it in the section on compound indexes in the book:MongoDB The Definitive Guide

2. Selectivity

Also, you want to use indexes selectively and write queries that limit the number of possible documents with the indexed field. To keep it simple, consider the following collection. If your index is {name:1}, If you run the query { name: "John", sex: "male"}. You will have to scan 1 document. Because you allowed MongoDB to be selective.

{_id:ObjectId(),name:"John",sex:"male"}
{_id:ObjectId(),name:"Rich",sex:"male"}
{_id:ObjectId(),name:"Mose",sex:"male"}
{_id:ObjectId(),name:"Sami",sex:"male"}
{_id:ObjectId(),name:"Cari",sex:"female"}
{_id:ObjectId(),name:"Mary",sex:"female"}

Consider the following collection. If your index is {sex:1}, If you run the query {sex: "male", name: "John"}. You will have to scan 4 documents.

{_id:ObjectId(),name:"John",sex:"male"}
{_id:ObjectId(),name:"Rich",sex:"male"}
{_id:ObjectId(),name:"Mose",sex:"male"}
{_id:ObjectId(),name:"Sami",sex:"male"}
{_id:ObjectId(),name:"Cari",sex:"female"}
{_id:ObjectId(),name:"Mary",sex:"female"}

Imagine the possible differences on a larger data set.


A little explanation of Compound Indexes

It’s easy to make the wrong assumption about Compound Indexes. According to MongoDB docs on Compound Indexes.

MongoDB supports compound indexes, where a single index structure holds references to multiple fields within a collection’s documents. The following diagram illustrates an example of a compound index on two fields:

enter image description here

When you create a compound index, 1 Index will hold multiple fields. So if we index a collection by {"sex" : 1, "name" : 1}, the index will look roughly like:

["male","Rick"] -> 0x0c965148
["male","John"] -> 0x0c965149
["male","Sean"] -> 0x0cdf7859
["male","Bro"] ->> 0x0cdf7859
...
["female","Kate"] -> 0x0c965134
["female","Katy"] -> 0x0c965126
["female","Naji"] -> 0x0c965183
["female","Joan"] -> 0x0c965191
["female","Sara"] -> 0x0c965103

If we index a collection by {"name" : 1, "sex" : 1}, the index will look roughly like:

["John","male"] -> 0x0c965148
["John","female"] -> 0x0c965149
["John","male"] -> 0x0cdf7859
["Rick","male"] -> 0x0cdf7859
...
["Kate","female"] -> 0x0c965134
["Katy","female"] -> 0x0c965126
["Naji","female"] -> 0x0c965183
["Joan","female"] -> 0x0c965191
["Sara","female"] -> 0x0c965103

Having {name:1} as the Prefix will serve you much better in using compound indexes. There is much more that can be read on the topic, I hope this can offer some clarity.

Published by codeblogforfun

Coder, blogger, traveler

Leave a comment

Design a site like this with WordPress.com
Get started