mongoui
Indexes·June 23, 2026·5 min read

How to create a unique index in MongoDB (and dedupe first)

A unique index stops MongoDB from ever storing two documents with the same value. The catch is you have to clear the existing duplicates before you can build it. Here is the syntax, the compound and partial variants, and the one that build error means.

Arctic Glass illustration for How to create a unique index in MongoDB (and dedupe first)

A unique index is MongoDB's promise that two documents will never share a value. It is the cleanest way to stop duplicates at the source: enforce it once at the database, and no application bug, race, or rogue script can slip a second one past it. The one thing to know before you run it is that you have to clear the existing duplicates first, because a unique index cannot be built over a collection that already breaks it.

The basic unique index

db.users.createIndex({ email: 1 }, { unique: true })

From now on, any insert or update that would create a second document with an email already in the collection is rejected with a duplicate key error. That is the whole feature, and it is a strong one: uniqueness enforced by the database is worth more than uniqueness checked in application code, because the database has no race conditions between the check and the write.

Unique on a combination of fields

Often the thing that must be unique is not one field but a pair. An order number unique per customer, say, not globally. That is a compound unique index:

db.orders.createIndex({ userId: 1, orderNumber: 1 }, { unique: true })

Now user 1 and user 2 can both have order number 1001, but user 1 cannot have two. The uniqueness applies to the combination, which is usually what identity actually means in your data.

The build that fails: dedupe first

Try to build a unique index on a collection that already has duplicates and it fails, loudly:

E11000 duplicate key error: users index: email_1 dup key: { email: "sam@example.com" }

This is not the index being difficult. It is the index refusing to make a promise the data already breaks. The fix is to clear the duplicates first, then build. Finding and removing them safely is its own job, covered in remove duplicates in MongoDB and the aggregation walk-through. Dedupe, then build, in that order. Reverse it and the build just fails again.

Partial unique: uniqueness for an optional field

Here is a subtle one that catches people. A plain unique index treats a missing field as null, and allows only a single null. So if email is optional, a plain unique index lets exactly one document omit it, and rejects the rest as duplicate nulls. That is almost never what you want.

The fix is a partial unique index that only applies to documents that actually have the field:

db.users.createIndex(
  { email: 1 },
  { unique: true, partialFilterExpression: { email: { $exists: true } } }
)

Now emails are unique among the documents that have one, and any number of documents can leave it out. Partial filters are the flexible, modern tool here; the older sparse option does something similar but is less precise. More on that in sparse and partial indexes.

Or dedupe with a dry run first

The riskiest moment is the cleanup before the build, because it deletes from a live collection. mongoui's duplicate finder groups documents on the key you are about to make unique, shows you the clusters, and runs the removal as a dry run first, with exact before and after counts and one-click undo. Then the unique index goes on cleanly. Its Index view confirms the index built and is being used, so it earns its place in your index budget. Everything runs on your machine, so the documents you are deduping never leave your network. Clear the duplicates, build the index, and let the database keep them gone.

Frequently asked questions

How do I create a unique index in MongoDB?

Pass the unique option: db.users.createIndex({ email: 1 }, { unique: true }). MongoDB then rejects any insert or update that would create a second document with the same email. The value has to be unique across the whole collection.

Why does my unique index build fail in MongoDB?

Because duplicate values already exist. A unique index cannot be built over a collection that violates it, so the build fails with an E11000 duplicate key error naming the conflict. Remove the existing duplicates first, then build the index.

How do I make a unique index on multiple fields in MongoDB?

Use a compound unique index: db.orders.createIndex({ userId: 1, orderNumber: 1 }, { unique: true }). It enforces uniqueness on the combination, so the same orderNumber can exist for different users but not twice for the same user.

How do I allow multiple documents without the field in a unique index?

Use a partial unique index. A plain unique index treats a missing field as null and allows only one such document. partialFilterExpression: { email: { $exists: true } } makes the index apply only to documents that have the field, so any number can omit it.