对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

在非分片键的字段上强制唯一性

如果无法使用唯一字段作为分片键,或者需要实施多个字段的唯一性,请创建另一个集合以充当代理集合。

仅当唯一索引位于分片键上或包含分片键作为前缀时,分片集群才会跨分片实施唯一约束。代理集合可以绕过该限制:代理集合包含对原始文档的引用和唯一键,并且您的应用程序会首先写入代理集合。

使用代理集合时,请考虑以下事项:

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

  • 如果代理集合需要分片,则必须对要强制唯一性的单个字段进行分片。

  • 每个字段都需要自己的代理集合。要使用分片的代理集合实施多个字段的唯一性,必须为每个字段设置一个代理集合。如果在单个代理集合上创建多个唯一索引,则无法对代理集合分片。

  • 这种方法需要为 primary_id字段创建唯一ID ,而不是让MongoDB在插入文档时自动创建。

有关应用于分片的片集合上唯一索引的完整约束设立,请参阅在分片集群中维护唯一性。

  • 标识需要唯一约束但不能作为分片键一部分的字段。

  • 确认现有文档不违反该字段的唯一性约束。

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

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

在 proxy集合的 email字段上创建唯一索引:

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

将包含目标字段和生成的唯一ID 的文档插入到 proxy集合中。如果操作成功,则将完整文档插入 records集合:

records = db.getCollection('records');
proxy = db.getCollection('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...
})