6
我们假设这是代表客户的文档。mongodb索引嵌入字段(点符号)
{
company_name: 'corporate ltd.',
pocs: [
{name: 'Paul', email: '[email protected]'},
{name: 'Jessica', email: '[email protected]'}
]
}
我想定义一个唯一索引pocs.email
所以我发出以下命令:
db.things.ensureIndex({"pocs.email": 1}, {unique: true})
奇怪的是,尝试添加另一家公司用POC有一个电子邮件地址已存在时在另一家公司,mongo拒绝这一点,尊重独特的索引约束。
也就是说,以下情况不能存在:
{
company_name: 'corporate ltd.',
pocs: [
{name: 'Paul', email: '[email protected]'},
{name: 'Jessica', email: '[email protected]'}
]
},
{
company_name: 'contoso llc',
pocs: [
{name: 'Paul', email: '[email protected]'},
]
}
这很好。然而,在同一文档中可能有重复的poc,例如,
{
company_name: 'corporate ltd.',
pocs: [
{name: 'Paul', email: '[email protected]'},
{name: 'Paul', email: '[email protected]'},
{name: 'Jessica', email: '[email protected]'}
]
},
看到我的CLI命令下面的顺序:
> version()
version: 2.0.2
>
> use test
switched to db test
> db.test.ensureIndex({"poc.email": 1}, {unique: true})
>
> db.test.insert({company: "contoso", poc: [{email: '[email protected]'}]})
> db.test.insert({company: "contoso", poc: [{email: '[email protected]'}]})
E11000 duplicate key error index: test.test.$poc.email_1 dup key: { : "[email protected]" }
> ({company: "contoso", poc: [{email: '[email protected]'}, {email: '[email protected]'}]})
>
>
> db.test.find()
{ "_id" : ObjectId("4f44949685926af0ecf9295d"), "company" : "contoso", "poc" : [ { "email" : "[email protected]" } ] }
{ "_id" : ObjectId("4f4494b885926af0ecf9295f"), "company" : "contoso", "poc" : [ { "email" : "[email protected]" }, { "email" : "[email protected]" } ] }
而且,这种情况无论是在insert
或update
。
> db.test.update({"_id" : ObjectId("4f44949685926af0ecf9295d")}, {$push: { poc: {email: '[email protected]'}}})
> db.test.find()
{ "_id" : ObjectId("4f4494b885926af0ecf9295f"), "company" : "contoso", "poc" : [ { "email" : "[email protected]" }, { "email" : "[email protected]" } ] }
{ "_id" : ObjectId("4f44949685926af0ecf9295d"), "company" : "contoso", "poc" : [ { "email" : "[email protected]" }, { "email" : "[email protected]" }, { "email" : "[email protected]" } ] }
>
这是一个错误或一个通过设计特征我错过了文档中的点滴?
+1。它被认为是一个错误,但是很奇怪。 “唯一的索引被设计用来强制执行只有一个文档拥有该密钥 从技术上讲,对于这种情况是这样的,但在大多数人使用该功能的方式中,他们希望独特的包含子文档。我不知道他们是否可以解决这个问题,因为这是一个非常大的语义变化,可能会咬人。 – Thilo 2012-02-22 08:04:25
@Thilo,我完全同意你的看法。如果他们接受它,它将会是一个巨大的变化,完全与独特的索引应该是什么性质相矛盾。大多数人误解了嵌入/子文档作为真实文档的概念。这是真正的问题。但是'嵌入式doc只是另一个领域(具有嵌套属性),并且只具有与普通领域相同的特征。如果他们明白这一点,这些问题就不会发生 – RameshVel 2012-02-22 08:22:51
@RameshVel或许这是一个观点问题,而不是[误解]理解概念。请参阅,如果嵌套数组有N个项目,则索引表中现在有N个条目,每个条目有一个条目。不像“唯一索引的性质”,它为每个记录的每个索引定义创建单个条目。 除此之外,如果我们要取出子文档并将它们放在一个单独的集合中,那么我们回到了从传统的RDBMS中知道的加入地狱。 – 2012-02-22 09:23:54