MongoDB 可选唯一索引

标签 mongodb indexing

我有一个 MongoDB 用户模式,看起来像这样:

{
  userId: "some-string",
  anonymousId: "some-other-string",
  project: {"$oid": "56d06bb6d9f75035956fa7ba"}
}

用户必须有一个 userId 或一个 anonymousId。由于用户属于一个项目,该模型还有一个名为 project 的引用,它链接到项目集合。

任何 userIdanonymousId 值在每个项目中都必须是唯一的,因此我创建了两个复合索引,如下所示:

db.users.createIndex({ "userId": 1, "project": 1 }, { unique: true })
db.users.createIndex({ "anonymousId": 1, "project": 1 }, { unique: true })

然而,由于不必同时提供 userIdanonymousId,而是只提供其中一个,MongoDB 会抛出一个 重复键null 值的 错误(例如,如果有第二个用户提供了 anonymousId 但没有 userId)。

因此,我尝试向复合索引添加一个 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/

相关文章:

mysql - 从哪里开始优化/添加索引以加快查询速度?

indexing - Julia:通过多个 boolean 比较获取子数组

javascript - 如何通知其他用户某个模式已打开

c# - Mongodb最好的查询方式

mysql - MySQL 是否记录它使用索引的频率?

python - 关于特定数组及其最终形状的 Numpy 奇特索引问题?

mysql - 如何优化datetime条件的查询?

javascript - 查询性能不佳

java - 如何考虑夏令时在 mongoDB 中存储 future 的调度日期

node.js - 如何使此函数返回数组中集合中所有文档的列表。我正在使用 mongodb 和 bluebird 吗?