In MongoDB, the db.collection.unhideIndex()
method unhides a hidden index.
A hidden index is one that’s hidden from the query planner. When you unhide an index, it is no longer hidden from the query planner, and it’s immediately available for use.
Example
Suppose we have a collection called pets
, and we want to check it for hidden indexes. We could run the following query to return all indexes on the collection:
db.pets.getIndexes()
Result:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "name" : 1, "type" : -1 }, "name" : "idx_name_1_type_-1" }, { "v" : 2, "key" : { "weight" : -1 }, "name" : "idx_weight_-1", "hidden" : true } ]
We can see that there are three indexes. The third one is hidden. We know that, because it has "hidden" : true
.
That index is on the weight
field. When we run a query through the query plan that queries the weight
field, we’ll see that it doesn’t use the index.
Example:
db.pets.find( { weight: { $gt: 10 } } ).explain()
Result:
{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "PetHouse.pets", "indexFilterSet" : false, "parsedQuery" : { "weight" : { "$gt" : 10 } }, "queryHash" : "CEB852E7", "planCacheKey" : "851FBDB5", "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "weight" : { "$gt" : 10 } }, "direction" : "forward" }, "rejectedPlans" : [ ] }, "ok" : 1 }
We can see that it did a COLLSCAN
(a collection scan), which means that it didn’t use the index.
Unhide the Index
We can use the unhideIndex()
method to unhide the index. This method accepts the name of the index or its key pattern as a parameter to specify which index to unhide.
Example:
db.pets.unhideIndex("idx_weight_-1")
Output:
{ "hidden_old" : true, "hidden_new" : false, "ok" : 1 }
The output of the unhideIndex()
method displays the old value for the hidden
field (in this case true
) and the new value (in this case false
).
However, if we unhide an already unhidden index (or hide an already hidden one), these aren’t displayed, and we just get the following:
{ "ok" : 1 }
Regardless, the index is now unhidden.
Re-Check the Query Plan
Let’s re-run the previous query to see what the query plan looks like now.
db.pets.find( { weight: { $gt: 10 } } ).explain()
Result:
{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "PetHouse.pets", "indexFilterSet" : false, "parsedQuery" : { "weight" : { "$gt" : 10 } }, "queryHash" : "CEB852E7", "planCacheKey" : "851FBDB5", "winningPlan" : { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "weight" : -1 }, "indexName" : "idx_weight_-1", "isMultiKey" : false, "multiKeyPaths" : { "weight" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "weight" : [ "[inf.0, 10.0)" ] } } }, "rejectedPlans" : [ ] }, "ok" : 1 }
We can see that it used IXSCAN
, which means that it used the index.
Check Whether the Index has been Unhidden
We can use the getIndexes()
method again to check whether or not the index has been unhidden.
db.pets.getIndexes()
Result:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "name" : 1, "type" : -1 }, "name" : "idx_name_1_type_-1" }, { "v" : 2, "key" : { "weight" : -1 }, "name" : "idx_weight_-1" } ]
We see the same three indexes that we saw in the earlier example, but this time we don’t see "hidden" : true
.
But we also don’t see "hidden" : false
.
Unhiding an index simply removes the "hidden" : true
part from the result of getIndexes()
. The hidden
option is only available if the value is true
. The hidden
option is a boolean value, so we can therefore infer that if it’s not "hidden" : true
, then it’s "hidden" : false
.
Can’t Hide/Unhide 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.