我有一个 MongoDB 用户模式,看起来像这样:
{
userId: "some-string",
anonymousId: "some-other-string",
project: {"$oid": "56d06bb6d9f75035956fa7ba"}
}
用户必须有一个 userId
或一个 anonymousId
。由于用户属于一个项目,该模型还有一个名为 project
的引用,它链接到项目集合。
任何 userId
或 anonymousId
值在每个项目中都必须是唯一的,因此我创建了两个复合索引,如下所示:
db.users.createIndex({ "userId": 1, "project": 1 }, { unique: true })
db.users.createIndex({ "anonymousId": 1, "project": 1 }, { unique: true })
然而,由于不必同时提供 userId
和 anonymousId
,而是只提供其中一个,MongoDB 会抛出一个 重复键
错误(例如,如果有第二个用户提供了 anonymousId 但没有 userId)。 null
值的
因此,我尝试向复合索引添加一个 sparse: true
标志,但这显然只有在两个字段都为空时才有效。我还尝试仅将稀疏标志添加到字段而不是复合索引,但这也不起作用。
举个例子,假设我在集合中有以下三个用户:
{ userId: "user1", anonymousId: null, project: {"$oid": "56d06bb6d9f75035956fa7ba"}}
{ userId: "user2", anonymousId: "anonym", project: {"$oid": "56d06bb6d9f75035956fa7ba"}}
{ userId: "user3", anonymousId: "random", project: {"$oid": "56d06bb6d9f75035956fa7ba"}}
以下应该是可能的:
- 我希望能够为同一项目插入另一个用户
{userId: "user4", anonymousId: null}
(不会出现重复键错误) - 但是,如果我尝试使用
{userId: "user3"}
插入另一个用户或使用{anonymousId: "random"}
插入另一个用户,则应该有一个重复键错误
我还能如何实现这一目标?
最佳答案
如果您使用的是 MongoDB 3.2,则可以使用唯一部分索引 而不是稀疏索引。
部分索引实际上比稀疏索引更推荐
示例
db.users.createIndex({ "userId": 1, "project": 1 },
{ unique: true, partialFilterExpression:{
userId: { $exists: true, $gt : { $type : 10 } } } })
db.users.createIndex({ "anonymousId": 1, "project": 1 },
{ unique: true, partialFilterExpression:{
anonymouseId: { $exists: true, $gt : { $type : 10 } } } })
在上面的例子中,只有当 userId
存在且不包含空值时,才会创建唯一索引。 anonymousId
也是如此。
请参阅https://docs.mongodb.org/manual/core/index-unique/#unique-partial-indexes
关于MongoDB 可选唯一索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35770538/