翻译或纠错本页面

Unique Constraints on Arbitrary Fields

On this page

If you cannot use a unique field as the shard key or if you need to enforce uniqueness over multiple fields, you must create another collection to act as a “proxy collection”. This collection must contain both a reference to the original document (i.e. its ObjectId) and the unique key.

Consider a collection records that stores user information. The field email is not the shard key, but needs to be unique.

The proxy collection then would contain the following:

{
  "_id" : ObjectId("...")
  "parent_id" : "<ID>"
  "email" : "<string>"
}

Use the following command to create a unique index on the email field:

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

The following example first attempts to insert a document containing the target field and a generated Unique ID into the proxy collection. If the operation is successful, then it inserts the full document into the records collection.

records = db.getSiblingDB('records');
proxy = db.getSiblingDB('proxy');

var primary_id = ObjectId();

proxy.insertOne({
   "_id" : primary_id
   "email" : "example@example.net"
})

// if: the above operation returns successfully,
// then continue:

records.insertOne({
   "_id" : primary_id
   "email": "example@example.net"
   // additional information...
})

Note that this methodology requires creating a unique ID for the primary_id field rather than letting MongoDB automatically create it on document insertion.

If you need to enforce uniqueness on multiple fields, then each field would require its own proxy collection.

See

The full documentation of: createIndex() and shardCollection.

Considerations

  • Your application must catch errors when inserting documents into the “proxy” collection and must enforce consistency between the two collections.
  • If the proxy collection requires sharding, you must shard on the single field on which you want to enforce uniqueness.
  • To enforce uniqueness on more than one field using sharded proxy collections, you must have one proxy collection for every field for which to enforce uniqueness. If you create multiple unique indexes on a single proxy collection, you cannot be able to shard proxy collections.