MongoDB 所有数组元素的唯一索引

Car*_*ath 5 arrays collections mongodb mongodb-query

我正在尝试为文档中的数组字段创建唯一索引。该索引应该像当我有一个包含包含两个元素的数组的文档时一样工作,然后如果我想添加一个新文档,其中数组字段如果包含这两个元素,那么应该会发生重复错误 - 但在只有一个元素是的情况下不会在另一个数组中重复。也许我会用这个例子来说明我的意思:

首先我创建一个简单的文档:

{
    "name" : "Just a name",
    "users" : [ 
        "user1", 
        "user2"
    ]
}
Run Code Online (Sandbox Code Playgroud)

我想在“用户”数组字段上创建唯一索引。我想要的结果是可以创建另一个这样的文档:

{
    "name" : "Just a name",
    "users" : [ 
        "user1", 
        "user3"
    ]
}
Run Code Online (Sandbox Code Playgroud)

或者

{
    "name" : "Just a name",
    "users" : [ 
        "user2", 
        "user5"
    ]
}
Run Code Online (Sandbox Code Playgroud)

但应该不可能创建第二个:

{
    "name" : "Just a name",
    "users" : [ 
        "user1", 
        "user2"
    ]
}
Run Code Online (Sandbox Code Playgroud)

或者反过来:

{
    "name" : "Just a name",
    "users" : [ 
        "user2", 
        "user1"
    ]
}
Run Code Online (Sandbox Code Playgroud)

但这是不可能的,因为 Mongo 给我一个错误,“users1”是重复的。是否可以在所有数组元素上创建唯一索引,如上所示?

kri*_*sad 4

根据Mongo 官方文档

对于唯一索引,唯一约束适用于集合中的各个文档,而不是单个文档

由于唯一约束适用于单独的文档,因此对于唯一的多键索引,只要该文档的索引键值不与另一个文档的索引键值重复,文档就可能具有导致重复索引键值的数组元素。

所以你不能插入第二个文档

{
"name" : "Just a name",
"users" : [ 
    "user1", 
    "user3"
]
}
Run Code Online (Sandbox Code Playgroud)

您将得到唯一约束的重复错误:

> db.st1.insert({"name":"Just a name","users":["user1","user3"]})
WriteResult({
   "nInserted" : 0,
   "writeError" : {
      "code" : 11000,
      "errmsg" : "E11000 duplicate key error collection: test.st1 index: users_1 dup key: { : \"user1\" }"
   }
})
Run Code Online (Sandbox Code Playgroud)

由于用户user1已经存在第一个文档的用户索引。

目前,您只有通过插入集合的代码来管理它的解决方案。在保存或更新之前创建验证逻辑并确保要施加的约束。