MongoDB Index Type and Properties
MongoDB Index Type and Properties
☰ Menu
(https://mydbops.files.wordpress.com/2022/11/image-2.png)
Index Types
(https://mydbops.files.wordpress.com/2022/11/screenshot-2022-11-22-at-9.38.17-pm.png)
Regardless of the specified index order, the unique characteristics of a single field index
allow traversal in both ascending and descending order.
For example, consider we are having an inventory collection with the following documents.
db.inventory.createIndex({item:1},{background:true})
Compound Index
A compound index is a single index that includes multiple fields. A compound index works
by storing a subset of a collection’s data in a sorted B-Tree data structure.
For example, consider we are having a people collection with the following documents.
This compound index creates a sorted B-Tree structure where records are first stored by
name in ascending order. The sorted records then store nested item values in descending
order.
Sort Order
Indexes store references to fields in either ascending (1) or descending (-1) sort order. For
single-field indexes, the sort order of keys doesn’t matter because MongoDB can traverse
the index in either direction. However, for compound indexes, sort order can matter in
determining whether the index can support a sort operation.
(https://mydbops.files.wordpress.com/2022/10/image-with-description.jpeg)
(https://mydbops.files.wordpress.com/2022/10/image-with-description-2.jpeg)
:
Multikey Index
MongoDB generates an index key for each element of an array to use when indexing a field
that contains an array value. These multikey indexes enable effective array field queries.
Multikey indexes can be built over arrays that contain nested documents as well as scalar
variables like characters and numbers.
For example, consider we have an inventory collection with the following documents.
1. Compound multikey indexes with multiple array fields are not permitted in MongoDB.
2. You are not allowed to specify a multikey index as the shard key index.
Geospatial Index
For example, consider we have restaurants collection with the following documents.
(https://www.mongodb.com/docs/manual/geospatial-queries/#2dsphere)
2dsphere
2d
:
Queries that compute geometries on a two-dimensional plane are supported by 2d indexes.
To create a 2d index, use the db.collection.createIndex() method, specifying the location field
as the key and the string literal “2d” as the index type.
You cannot use a geospatial index as a shard key when sharding a collection.
Text Indexes
Any field whose value is a string or an array of string elements can be included in text
indexes. A collection can only have one text search index, although that index can have
several fields.
For example, consider we have a stores collection with the following documents.
db.stores.createIndex({name:"text"},{background:true})
db.stores.createIndex({name:"text",description:"text"},
{background:true})
:
We can also create compound indexes, including a mix of text and traditional indexes.
db.stores.createIndex({name:"text",phoneno:1},
{background:true})
Text index can be very large and can take a long time to create.
MongoDB recommends having enough memory on your system to keep the text index
in memory otherwise there may be significant IO involved during the search.
Hashed Indexes
To maintain the entries with hashes of the values of the indexed field (mostly _id field in all
collections), we use Hash Index. These indexes have a more random distribution of values
along their range, but only support equality matches and cannot support range-based
queries.
For example, consider we have an inventory collection with the following documents.
Hashed indexes tend to be smaller than scalar indexes because only a hash of the key is
stored instead of the full key. E.g. For a simple test with 100k documents, we added hashed
and scalar indexes on a string field – fieldName. As shown below, the hashed index tends to
be considerably smaller than the scalar indexes
“indexSizes” : {
Wildcard Indexes
MongoDB 4.2 introduces wildcard indexes for supporting queries against unknown or
arbitrary fields.
A wildcard index is a type of filter that automatically matches any field, sub-document or
array in a collection and indexes those matches.
For example, suppose we have a data collection with the following documents.
{ _id: 5, Data:{A:2145,B:740,C:2013}}
{ _id: 5, Data:{A:1405,B:6740,C:213}}
{ _id: 5, Data:{A:1245,B:7140,C:1213}}
{ _id: 5, Data:{A:1465,B:7030,C:21673}}
:
Queries might be issued against any one of the attributes in the data sub-document.
Furthermore, the application may add new fields that we can’t estimate. We need to create a
separate index for each field to optimise performance.
db.data.createIndex({_id:1,”Data.A”:1},{background:true})
db.data.createIndex({_id:1,”Data.B”:1},{background:true})
db.data.createIndex({_id:1,”Data.C”:1},{background:true})
It requires creating too many indexes but even this won’t work unless we know for sure if
no new fields are added under Data.
db.data.createIndex( { "Data.$**" : 1 } )
The statement creates an index on every field in the Data sub-document. Even if new fields
are created by an application after the index is created.
To index the value of all fields in a document (excluding _id ), specify "$**" as the
index key.
db.collection.createIndex( { "$**" : 1 } )
With this wildcard index, MongoDB indexes all fields for each document in the collection. If
a given field is a nested document or array, the wildcard index recurses into the
document/array and stores the value for all fields in the document/array.
1. MongoDB cannot use a non-wildcard index to satisfy one part of a query predicate and a
wildcard index to satisfy another.
:
2. MongoDB cannot use one wildcard index to satisfy one part of a query predicate and
another wildcard index to satisfy another.
3. Even if a single wildcard index could support multiple query fields, MongoDB can use
the wildcard index to support only one of the query fields. All remaining fields are
resolved without an index.
4. Wildcard indexes don’t support compound, TTL, Text, Geospatial, Hashed and Unique
indexes.
Hidden Index
A hidden index is simply a regular index that is not visible to the query planner. When
evaluating the execution plans, MongoDB ignores such kinds of indexes.
For example, consider we have an inventory collection with the following documents.
:
{ _id: 5, type: “food”, item: “aaa”, ratings: [ 6.5, 8, 9 ] }
db.inventory.createIndex({type:1},{hidden:true})
db.inventory.hideIndex( {type: 1} )
db.inventory.unhideIndex( {type: 1} )
Index Properties
Unique Index
:
A unique index ensures that the indexed fields do not store duplicate values i.e. enforces
uniqueness for the indexed fields. By default, MongoDB creates a unique index on the _id
field during the creation of a collection.
Often, you want to ensure that the values of a field are unique across documents in a
collection, such as a code or a username.
Use the createIndex() method with the option { unique: true } to create a unique index and
compound a unique index.
db.people.createIndex( { code:1} ,
{unique:true,background:true})
Partial indexes index only documents in a collection that matches a specific filter
expression. If you specify both a partial filter expression and a unique constraint, the
unique constraint applies only to documents that match the filter expression.
Unique Partial indexes introduce in version 3.2.
1. MongoDB cannot create a unique index on the specified index fields if the collection
already contains data that would violate the unique constraint for the index.
2. You may not specify a unique constraint on a hashed index.
Partial Index
Partial indexes only index the documents in a collection that meet a specified filter
expression. By indexing a subset of the documents in a collection, partial indexes have lower
storage requirements and reduced performance costs for index creation and maintenance.
The partialFilterExpression option accepts a document that specifies the filter condition
using:
Example:
In 5.0 earlier versions of MongoDB, creating multiple partial indexes is not allowed when
using the same key pattern with different partialFilterExpressions.
You cannot specify both the partialFilterExpression option and the sparse option.
Sparse Indexes
The sparse property of an index ensures that the index only contains entries for documents
that have the indexed field. The index skips documents that do not have the indexed field.
Example:
If a sparse index would result in an incomplete result set for queries and sort operations,
MongoDB will not use that index unless a hint() explicitly specifies the index.
For example, the query { x: { $exists: false } } will not use a sparse index on the x field unless
explicitly hinted. See Sparse Index On A Collection Cannot Return Complete Results for an
example that details the behaviour.
:
Changed in version 3.4.
If you include a hint() that specifies a sparse index when you perform a count() of all
documents in a collection (i.e. with an empty query predicate), the sparse index is used even
if the sparse index results in an incorrect count.
db.collection.insertOne( { _id: 1, y: 1 } )
db.collection.find().hint( { x: 1 } ).count()
To obtain the correct count, do not hint() with a sparse index when performing a count of all
documents in a collection.
db.collection.find().count()
db.collection.createIndex( { y: 1 } )
db.collection.find().hint( { y: 1 } ).count()
Partial indexes should be preferred over sparse indexes. Partial indexes provide the
following benefits:
Sparse indexes select documents to index only based on the existence of the indexed field, or
for compound indexes, the existence of the indexed fields.
The partial index can also specify filter expressions on fields other than the index key. For
example, the following operation creates a partial index, where the index is on the
“name” field but the filter expression is on the “email” field.
You are strongly encouraged to consider partial indexes if you have one or more of these
use cases.
:
Hybrid Index Build
Starting in MongoDB 4.2, index builds obtain an exclusive lock on only the collection
being indexed during the start and end of the build process to protect metadata changes.
The rest of the build process uses the yielding behaviour of background index builds to
maximize read-write access to the collection during the build.
4.2 index builds still produce efficient index data structures despite the more permissive
locking behaviour.
We hope that after reading these blogs you have an idea about the types of indexes and
their properties. In upcoming blogs, we will come up with a terminate-in-progress index
build. Happy Learning!!!