MongoDBSingle-Field Indexes

Single-Field Indexes

A single-field index covers exactly one field. It's the simplest index type, and the one you'll create most often to support equality and range filters, plain sorts, and existence checks on an individual field.

Creating One

Ascending single-field index

JS
db.products.createIndex({ price: 1 })
db.products.find({ price: { $gte: 10, $lte: 50 } })   // uses the index
Does Direction Matter for a Single Field?

For a single-field index, ascending (1) vs descending (-1) makes no practical difference — a B-tree can be walked in either direction with equal efficiency. sort({ price: 1 }) and sort({ price: -1 }) are both served just as well by an index created as { price: 1 }.

One index, both sort directions

JS
db.products.createIndex({ price: 1 })

db.products.find().sort({ price: 1 })    // walks the index forward
db.products.find().sort({ price: -1 })   // walks the SAME index backward — equally fast
Note
Direction only starts to matter once you have a compound index with multiple sort fields — see the Compound Index page for how mixed ascending/descending order affects which multi-field sorts an index can serve.
Indexing Nested Fields (Dot Notation)

Indexing an embedded field

JS
db.users.createIndex({ "address.city": 1 })
db.users.find({ "address.city": "Toronto" })   // uses the index
Indexing Array Fields — Multikey

Create a single-field index on a field that happens to hold an array, and MongoDB automatically builds it as a multikey index: one index entry per array element, per document, rather than one entry per document.

An index on an array field becomes multikey automatically

JS
db.posts.createIndex({ tags: 1 })

db.posts.insertOne({ _id: 1, tags: ["mongodb", "nosql", "database"] })
// This ONE document creates THREE index entries — one per tag —
// each pointing back to the same document.

db.posts.find({ tags: "nosql" })   // uses the multikey index

See the dedicated Multikey Index page for the full mechanics and limitations — the important thing here is that you don't do anything special to opt in; MongoDB detects the array and builds a multikey index automatically.

The sparse Option

By default, an index includes an entry for every document, even ones missing the indexed field (indexed as if the value were null). A sparse index skips documents that don't have the field at all — smaller index, but queries against it may miss documents you'd expect to match null.

Sparse index — skip documents missing the field

JS
db.users.createIndex({ referralCode: 1 }, { sparse: true, unique: true })
// Only documents that HAVE a referralCode are indexed and checked for uniqueness.
// Documents with no referralCode at all don't collide with each other,
// unlike a plain unique index where multiple missing fields would all
// be treated as null and collide.
Warning
A non-sparse unique index treats every document missing the field as having the value null — so a second document also missing that field triggers a duplicate key error. If a field is optional and you want a unique index on it, combine unique: true with sparse: true (or a partial filter expression) so multiple documents can all omit it without colliding.
Case-Insensitive Indexing via Collation

A plain index compares strings byte-by-byte (case-sensitive). To support case-insensitive equality/sort queries efficiently, build the index with a collation that matches the queries you'll run against it.

Case-insensitive index via collation

JS
db.users.createIndex(
  { email: 1 },
  { collation: { locale: "en", strength: 2 } }   // strength 2 = case-insensitive
)

// This query can use the collated index because it specifies the SAME collation
db.users.find({ email: "Alice@Example.com" }).collation({ locale: "en", strength: 2 })
Warning
A query must specify a **matching** collation to use a collation-built index — a plain query with no .collation() call uses the server's default (binary) comparison and will not use a collated index, even if one exists on the same field.
Inspecting Indexes
test> db.users.getIndexes()
[
  { v: 2, key: { _id: 1 }, name: '_id_' },
  { v: 2, key: { 'address.city': 1 }, name: 'address.city_1' },
  {
    v: 2,
    key: { email: 1 },
    name: 'email_1',
    collation: { locale: 'en', strength: 2, ... }
  }
]
  • Direction (1 vs -1) is irrelevant for a single-field index — it serves both sort directions equally well.

  • Indexing a nested field uses dot notation: { "address.city": 1 }.

  • Indexing an array field is automatic — MongoDB builds a multikey index without any special syntax.

  • sparse: true excludes documents missing the field — usually paired with unique: true on optional fields.

  • Case-insensitive queries need both a collated index AND a matching .collation() on the query to actually use it.