任意字段上的唯一约束
本页内容
如果您不能使用唯一字段作为分片键,或者如果需要在多个字段上强制唯一性,您必须创建另一个集合来作为“代理集合”。这个集合必须包含对原始文档的引用(即其ObjectId
)和唯一键。
考虑一个名为records
的集合,该集合存储用户信息。字段email
不是分片键,但需要保持唯一。
那么代理集合将包含以下内容
{ "_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" : "example@example.net" }) // if: the above operation returns successfully, // then continue: records.insertOne({ "_id" : primary_id "email": "example@example.net" // additional information... })
请注意,这种方法需要在primary_id
字段上创建唯一ID,而不是让MongoDB在文档插入时自动创建它。
如果您需要在多个字段上强制唯一性,则每个字段都需要自己的代理集合。
注意事项
您的应用程序必须在将文档插入“代理”集合时捕获错误,并必须在两个集合之间强制一致性。
如果代理集合需要分片,则必须在您想要强制唯一性的单个字段上进行分片。
要使用分片代理集合在多个字段上强制唯一性,您必须为要强制唯一性的每个字段创建一个代理集合。如果您在单个代理集合上创建多个唯一索引,则无法分片代理集合。