任意场的唯一约束

在本页面

如果您不能使用唯一字段作为分片键,或者需要在多个字段上强制唯一性,则必须创建另一个collection来充当“代理集合”。此集合必须同时包含对原始文档的引用(即其ObjectId)和唯一键。

考虑一个存储用户信息的集合records。字段email不是分片键,但必须是唯一的。

proxy集合将包含以下内容:

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

使用以下命令在email字段上创建唯一索引:

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

以下示例首先尝试将包含目标字段和生成的唯一 ID 的文档插入proxy集合。如果操作成功,则它将整个文档插入records集合。

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

var primary_id = ObjectId();

proxy.insertOne({
   "_id" : primary_id
   "email" : "[email protected]"
})

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

records.insertOne({
   "_id" : primary_id
   "email": "[email protected]"
   // additional information...
})

请注意,此方法需要为primary_id字段创建唯一的 ID,而不是让 MongoDB 在插入文档时自动创建它。

如果您需要在多个字段上强制唯一性,则每个字段都需要自己的代理集合。

See

完整的文档:createIndex()shardCollection

Considerations

  • 将文档插入“代理”集合时,您的应用程序必须捕获错误,并且必须在两个集合之间保持一致性。

  • 如果代理集合需要分片,则必须在要实施唯一性的单个字段上分片。

  • 要使用分片代理集合对多个字段实施唯一性,您必须为每个字段具有一个代理集合,才能对其实施唯一性。如果您在单个代理服务器集合上创建多个唯一索引,那么您将无法分片代理服务器集合。