3 Ways to Hide an Index from the Query Plan in MongoDB

Starting from MongoDB 4.4, we can now hide indexes from the query plan. This enables us to evaluate the potential impact of dropping an index without actually dropping the index.

If hiding it has a negative impact, we can unhide the index. This saves us from having to drop the index, then recreate it again.

Below are 3 ways to hide an index in MongoDB.

The hideIndex() Method

The db.collection.hideIndex() method does exactly as it promises – it hides the index (from the query planner).

Example:

db.pets.hideIndex("idx_weight_-1")

Output:

{ "hidden_old" : false, "hidden_new" : true, "ok" : 1 }

That hides an index called idx_weight_-1 on the pets collection. We could alternatively provided the key pattern for the index instead of the name.

The output of the hideIndex() method displays the old value for the hidden field (in this case false) and the new value (in this case true).

However, if we hide an already hidden index (or unhide an already unhidden one), these aren’t displayed, and we just get the following:

{ "ok" : 1 }

In any case, the index is now hidden.

The hideIndex() method is actually a wrapper for the collMod administration command (below).

The collMod Command

The collMod administration command enables us to add options to a collection or to modify view definitions.

We can use it to hide an index by passing hidden: true.

Example:

db.runCommand( {
   collMod: "pets",
   index: {
      name: "idx_weight_-1",
      hidden: true
   }
} )

Result:

{ "hidden_old" : false, "hidden_new" : true, "ok" : 1 }

This returns the same document that hideIndex() returns.

Similar to hideIndex(), you have the option of specifying the index name or its key pattern.

Here’s an example of using the key pattern:

db.runCommand( {
   collMod: "pets",
   index: {
      keyPattern: { weight : -1 },
      hidden: true
   }
} )

In this case, the index was defined using { weight : -1 }, and so this definition can be used instead of the index name.

To verify this, we can use getIndexes() to see the index’s definition:

db.pets.getIndexes()

Result:

[
	{
		"v" : 2,
		"key" : {
			"_id" : 1
		},
		"name" : "_id_"
	},
	{
		"v" : 2,
		"key" : {
			"weight" : -1
		},
		"name" : "idx_weight_-1",
		"hidden" : true
	}
]

We can also unhide the index by passing hidden: false.

Create a Hidden Index

The third way to hide an index is to create it as a hidden index.

To do this, use hidden: true as one of the options when you create the index.

Example:

db.pets.createIndex( 
    { type: 1 },
    { hidden: true }
)

Output:

{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 2,
	"numIndexesAfter" : 3,
	"ok" : 1
}

Now let’s call getIndexes() again to check our newly created hidden index:

db.pets.getIndexes()

Result:

[
	{
		"v" : 2,
		"key" : {
			"_id" : 1
		},
		"name" : "_id_"
	},
	{
		"v" : 2,
		"key" : {
			"weight" : -1
		},
		"name" : "idx_weight_-1",
		"hidden" : true
	},
	{
		"v" : 2,
		"hidden" : true,
		"key" : {
			"type" : 1
		},
		"name" : "type_1"
	}
]

We can see that it has been created with "hidden": true.

Can’t Hide Indexes? Check this Setting.

The mongod featureCompatibilityVersion must be at least 4.4 before you can hide indexes. However, once hidden, an index will remain hidden even with featureCompatibilityVersion set to 4.2 on MongoDB 4.4 binaries.

You can check the featureCompatibilityVersion setting with the following code:

db.adminCommand( 
    { 
        getParameter: 1, 
        featureCompatibilityVersion: 1 
    } 
)

You can set it using the setFeatureCompatibilityVersion command:

db.adminCommand( { setFeatureCompatibilityVersion: "4.4" } )

The setFeatureCompatibilityVersion command needs to be run in the admin database.

Also note, you cannot hide the _id index.