数组字段上的唯一复合索引

Posted

技术标签:

【中文标题】数组字段上的唯一复合索引【英文标题】:Unique compound index on array fields 【发布时间】:2018-08-15 17:51:14 【问题描述】:

我正在尝试使用复合索引创建 mongo 文档。我的示例文档如下所示

fname: "fname1", lname:“lname1”, 任务:[“t11”,“t12”,“t13”]

fname: "fname2", lname:“lname2”, 任务:[“t21”,“t22”,“t23”]

fname: "fname3", lname : "lname3", 任务:[“t31”,“t32”,“t33”]

索引如下

createIndex( fname: 1, lname: 1, task: 1 , unique: true, name: 'some-index-name')

我期待的是

如果有任何变化

fname lname 任务(任何部分数据更改 - 至少一个元素)

应被视为唯一文档。

我遇到了这个异常 "E11000重复键错误采集"

我查看了闲置的链接。但无法弄清楚。

What are the limitations of partial indexes?

https://docs.mongodb.com/manual/core/index-partial/

https://docs.mongodb.com/manual/indexes/#create-an-index

Mongo 代码库: https://github.com/mongodb/mongo/blob/69dec2fe8fed6d32ec4998ea7ec7ab063cb5b788/src/mongo/db/catalog/index_catalog.cpp#L422

【问题讨论】:

【参考方案1】:

您是正确的,唯一索引的限制正如您所描述的那样。但是,这仅适用于 singular value 字段。一旦你在一个数组上使用了唯一索引,它就会成为一个唯一+多键索引。

基本上,当您在数组字段上创建索引时,MongoDB 会为该文档中的每个数组字段创建一个索引条目。这称为多键索引。

例如文档:

a:1, b:[1, 2, 3]

带索引:

db.test.createIndex(a:1, b:1)

对于b 的每个数组元素,索引中将包含三个条目:

a:1, b:1
a:1, b:2
a:1, b:3

因此,如果您在字段 ab 上创建唯一索引:

db.test.createIndex(a:1, b:1, unique:true)

所有这些插入都会因违反唯一索引而失败:

> db.test.insert(a:1, b:1)
E11000 duplicate key error collection: test.test index: a_1_b_1 dup key:  : 1.0, : 1.0 

> db.test.insert(a:1, b:2)
E11000 duplicate key error collection: test.test index: a_1_b_1 dup key:  : 1.0, : 2.0 

> db.test.insert(a:1, b:3)
E11000 duplicate key error collection: test.test index: a_1_b_1 dup key:  : 1.0, : 3.0 

> db.test.insert(a:1, b:[1])
E11000 duplicate key error collection: test.test index: a_1_b_1 dup key:  : 1.0, : 1.0 

> db.test.insert(a:1, b:[1,2])
E11000 duplicate key error collection: test.test index: a_1_b_1 dup key:  : 1.0, : 1.0 

> db.test.insert(a:1, b:[1,2,3])
E11000 duplicate key error collection: test.test index: a_1_b_1 dup key:  : 1.0, : 1.0 

这就是为什么不能在一个索引中索引多个数组字段的原因。如果您有多个数组,则索引条目的数量将是两个数组长度的乘积。您的索引可能很容易大于您的数据,并且扫描如此大的索引可能需要相当长的时间。

【讨论】:

能否请您提供任何官方文档链接,以便大家更好地理解。谢谢。 @RameshPapaganti 官方文档是docs.mongodb.com/manual/core/index-multikey,感兴趣的是页面下方的示例部分。

以上是关于数组字段上的唯一复合索引的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 复合索引设计原理——前缀性和可选性

MongoDB索引问题

MongoDB + C#:未选择/使用 GUID 字段上的复合索引

索引的分类,优缺点,使用

通俗易懂 索引单列索引复合索引主键唯一索引聚簇索引非聚簇索引唯一聚簇索引 的区别与联系

mysql 复合 唯一 索引