Docs Home / Indexes / Properties

Unique Indexes唯一索引

A unique index ensures that the indexed fields do not store duplicate values, and that a value appears at most once for a given field. A unique compound index ensures that any given combination of the index key values only appears at most once. By default, MongoDB creates a unique index on the _id field during the creation of a collection.唯一索引可确保索引字段不存储重复值,并且给定字段的值最多出现一次。唯一的复合索引可确保索引键值的任何给定组合最多只出现一次。默认情况下,MongoDB在创建集合时在_id字段上创建一个唯一索引。

You can create and manage unique indexes in the UI for deployments hosted in MongoDB Atlas.您可以在MongoDB Atlas中托管的部署的UI中创建和管理唯一索引

Create a Unique Index创建唯一索引

To create a unique index, use the db.collection.createIndex() method with the unique option set to true.要创建唯一索引,请使用db.collection.createIndex()方法,并将unique选项设置为true

db.collection.createIndex( <key and index type specification>, { unique: true } )

Unique Index on a Single Field单个字段上的唯一索引

For example, to create a unique index on the email field of the users collection, use the following operation in mongosh:例如,要在users集合的email字段上创建唯一索引,请在mongosh中使用以下操作:

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

Unique Compound Index唯一复合指数

You can also enforce a unique constraint on compound indexes. A unique compound index enforces uniqueness on the combination of the index key values.您还可以对复合索引实施唯一约束。唯一复合索引强制索引键值组合的唯一性。

For example, to create a unique index on name, email, and password fields of the users collection, use the following operation in mongosh:例如,要在users集合的nameemailpassword字段上创建唯一索引,请在mongosh中使用以下操作:

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

The created index enforces uniqueness for the combination of name, email, and password values.创建的索引强制nameemailpassword值的组合具有唯一性。

Create a unique compound multikey index on email and name:emailname上创建一个唯一的复合多键索引:

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

The unique index permits the insertion of the following documents into the collection since the index enforces uniqueness for the combination of email and name values:唯一索引允许将以下文档插入到集合中,因为该索引强制emailname值的组合具有唯一性:

db.users.insertMany( [
{ name: "Catelyn Stark", email: [ "catelyn@gameofthron.es", "sean_bean@gameofthron.es" ], password: "$2b$12$hash2" },
{ name: "Arya Stark", email: [ "catelyn@gameofthron.es" ], password: "$2b$12$hash3" }
] )

Even though both documents have "catelyn@gameofthron.es" in their email arrays, the operation succeeds because the combination of each email value with the name field is unique.尽管这两份文件都有"catelyn@gameofthron.es"在他们的email数组中,操作成功,因为每个电子邮件值与name字段的组合都是唯一的。

Behavior行为

Restrictions限制

MongoDB cannot create a unique index on the specified index field(s) if the collection already contains data that would violate the unique constraint for the index.如果集合中已包含违反索引唯一约束的数据,MongoDB无法在指定的索引字段上创建唯一索引。

You may not specify a unique constraint on a hashed index.您不能在哈希索引上指定唯一约束。

Building Unique Index on Replica Sets and Sharded Clusters在副本集和分片集群上构建唯一索引

For replica sets and sharded clusters, using a rolling procedure to create a unique index requires that you stop all writes to the collection during the procedure. 对于副本集和分片集群,使用滚动过程创建唯一索引需要在过程中停止对集合的所有写入。If you cannot stop all writes to the collection during the procedure, do not use the rolling procedure. Instead, to build your unique index on the collection you must either:如果在此过程中无法停止对集合的所有写入,请不要使用滚动过程。相反,要在集合上构建唯一索引,您必须:

  • Run db.collection.createIndex() on the primary for a replica set在副本集的主服务器上运行db.collection.createIndex()
  • Run db.collection.createIndex() on the mongos for a sharded cluster对分片集群的mongos运行db.collection.createIndex()

Unique Constraint Across Separate Documents跨单独文档的唯一约束

The unique constraint applies to separate documents in the collection. That is, the unique index prevents separate documents from having the same value for the indexed key.唯一约束适用于集合中的单独文档。也就是说,唯一索引可以防止单独的文档对索引键具有相同的值。

Because the constraint applies to separate documents, for a unique multikey index, a document may have array elements that result in repeating index key values as long as the index key values for that document do not duplicate those of another document. 由于约束适用于单独的文档,因此对于唯一的多键索引,只要该文档的索引键值不与另一个文档的索引键值重复,文档中的数组元素可能会导致重复的索引键值。In this case, the repeated index entry is inserted into the index only once.在这种情况下,重复的索引条目只插入索引一次。

For example, create a unique compound multikey index on email and name:例如,在emailname上创建一个唯一的复合多键索引:

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

The unique index permits the insertion of the following document into the collection if no other document in the collection has an index key value of { "email": "arya@winterfell.com", "name": null }.如果集合中没有其他文档的索引键值为{ "email": "arya@winterfell.com", "name": null }

db.users.insertOne( { _id: ObjectId("59b99db4cfa9a34dcd7885b9"), email: [ "arya@winterfell.com", "arya@gameofthron.es" ] } )

Missing Document Field in a Unique Single-Field Index唯一单字段索引中缺少文档字段

If a document has a null or missing value for the indexed field in a unique single-field index, the index stores a null value for that document. 如果文档的唯一单字段索引中的索引字段值为null或缺失,则索引会为该文档存储null值。Because of the unique constraint, a single-field unique index can only contain one document that contains a null value in its index entry. 由于唯一约束,单个字段唯一索引只能包含一个索引条目中包含null值的文档。If there is more than one document with a null value in its index entry, the index build fails with a duplicate key error.如果多个文档的索引条目中有null值,则索引构建将失败,并出现重复键错误。

For example, a collection has a unique single-field index on email:例如,一个集合在email上有一个唯一的单字段索引:

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

The unique index allows the insertion of a document without the field email if the collection does not already contain a document missing the field email:如果集合中尚未包含缺少字段email的文档,则唯一索引允许插入没有字段email的文件:

db.users.insertOne( { name: "Arya Stark" } )

However, you cannot insert a second document without the field email if the collection already contains a document missing the field password. 但是,如果集合中已包含缺少字段password的文档,则无法插入没有字段email的第二个文档。A second operation that attempts to insert another document without the email field fails to insert the document because of the violation of the unique constraint on email field.由于违反了email字段的唯一约束,尝试插入另一个没有email字段的文档的第二个操作无法插入文档。

Unique Partial Indexes唯一部分索引

Partial indexes only index the documents in a collection that meet a specified filter expression. 部分索引仅对集合中满足指定筛选表达式的文档进行索引。If you specify both the partialFilterExpression and a unique constraint, the unique constraint only applies to the documents that meet the filter expression.如果同时指定partialFilterExpressionunique约束,则唯一约束仅适用于符合筛选表达式的文档。

A partial index with a unique constraint does not prevent the insertion of documents that do not meet the unique constraint if the documents do not meet the filter criteria. For an example, see Partial Index with Unique Constraint.如果文档不符合筛选条件,则具有唯一约束的部分索引不会阻止插入不符合唯一约束的文档。例如,请参阅具有唯一约束力的部分索引

Sharded Clusters and Unique Indexes分片群集和唯一索引

You cannot specify a unique constraint on a hashed index.不能对哈希索引指定唯一约束。

For a ranged sharded collection, only the following indexes can be unique:对于范围分片集合,只有以下索引可以是唯一的

  • the index on the shard key分片键上的索引
  • a compound index where the shard key is a prefix一个复合索引,其中分片键是前缀
  • The default _id index; however, the _id index only enforces the uniqueness constraint per shard if the _id field is not the shard key.默认_id索引;但是,如果_id字段不是分片键,_id索引只会强制每个分片的唯一性约束。

Important

Sharded clusters do not enforce the uniqueness constraint on _id fields across the cluster when the _id field is not the shard key._id字段不是分片键时,分片集群不会对整个集群的_id字段强制执行唯一性约束。

If the _id field is not the shard key, the uniqueness constraint only applies to the shard that stores the document. This means that two or more documents can have the same _id value, provided they occur on different shards.如果_id字段不是分片键,则唯一性约束仅适用于存储文档的分片。这意味着两个或多个文档可以具有相同的_id值,只要它们出现在不同的分片上。

For example, consider a sharded collection with shard key {x: 1} that spans two shards A and B. Because the _id key is not the shard key, the collection could have a document with _id value 1 in shard A and another document with _id value 1 in shard B.例如,考虑一个分片集合,其分片键{x: 1}跨越两个分片a和B。由于_id键不是分片键,该集合可能在分片A中有一个_id值为1的文档,在分片B中有另一个_id价值为1的文件。

In cases where the _id field is not the shard key, MongoDB expects applications to ensure the uniqueness of _id values across the shards, for example, by using a unique identifier to populate the _id field._id字段不是分片键的情况下,MongoDB希望应用程序确保_id值在分片之间的唯一性,例如,通过使用唯一标识符填充_id字段。

The unique index constraints mean that:独特的指数约束意味着:

  • For a to-be-sharded collection, you cannot shard the collection if the collection has multiple unique indexes unless the shard key is the prefix for all the unique indexes.对于要分片的集合,如果集合有多个唯一索引,则不能对集合进行分片,除非分片键是所有唯一索引的前缀。
  • For an already-sharded collection, you cannot create unique indexes on other fields unless the shard key is included as the prefix.对于已经分片的集合,除非分片键作为前缀包含在内,否则无法在其他字段上创建唯一索引。
  • A unique index stores a null value for a document missing the indexed field; that is a missing index field is treated as another instance of a null index key value. 唯一索引为缺少索引字段的文档存储一个null值;即缺失的索引字段被视为空索引键值的另一个实例。For more information, see Missing Document Field in a Unique Single-Field Index.有关详细信息,请参阅唯一单字段索引中缺少文档字段

To maintain uniqueness on a field that is not your shard key, see Unique Constraints on Arbitrary Fields.要保持非分片键字段的唯一性,请参阅任意字段的唯一约束

Sparse and Non-Sparse Unique Indexes稀疏和非稀疏唯一索引

Starting in MongoDB 5.0, unique sparse and unique non-sparse indexes with the same key pattern can exist on a single collection.从MongoDB 5.0开始,具有相同键模式的唯一稀疏唯一非稀疏索引可以存在于单个集合上。

Unique and Sparse Index Creation独特而稀疏的索引创建

This example creates multiple indexes with the same key pattern and different sparse options:此示例使用相同的键模式和不同的sparse选项创建多个索引:

db.users.createIndex( { password : 1 }, { name: "unique_index", unique: true } )
db.users.createIndex( { password : 1 }, { name: "unique_sparse_index", unique: true, sparse: true } )

Basic and Sparse Index Creation基本和稀疏索引创建

You can also create basic indexes with the same key pattern with and without the sparse option:您还可以在有和没有稀疏选项的情况下,使用相同的键模式创建基本索引:

db.users.createIndex( { password : 1 }, { name: "sparse_index", sparse: true } )
db.users.createIndex( { password : 1 }, { name: "basic_index" } )

Basic and Unique Indexes With Duplicate Key Patterns具有重复键模式的基本索引和唯一索引

Starting in MongoDB 5.0, basic and unique indexes can exist with the same key pattern.从MongoDB 5.0开始,基本索引和唯一索引可以以相同的键模式存在。

This duplication in key patterns allows for adding a unique index to already indexed fields.键模式中的这种重复允许为已索引的字段添加唯一索引。

For example, you can create both of the following indexes that use the same key pattern:例如,您可以创建以下两个使用相同键模式的索引:

db.users.createIndex( { email : 1 }, { name: "basic_index" } )
db.users.createIndex( { email : 1 }, { name: "unique_index", unique: true } )