2013-06-05 54 views
2

我试图在MongoDB中的一组字段上添加唯一索引。并非所有这些字段都可用于所有文档,我只想索引那些包含所有字段的字段。在MongoDB中添加唯一索引,忽略空值

所以,我试图运行这个命令:

db.mycollection.ensureIndex({date:1, type:1, reference:1}, {sparse: true, unique: true}) 

但我上错过“类型”字段的字段得到一个错误E11000 duplicate key error index(有很多人,他们是重复的,但我只是想忽略它们)。

是否有可能在MongoDB中或有一些解决方法?

+0

稀疏手段不索引缺少您要索引的字段的文档。这对复合索引没有意义,除非您想跳过没有设置任何字段的文档。 –

+0

@AsyaKamsky是的,我知道它是如何工作的,我正在寻找解决这个限制的解决方法。 – sashkello

+0

已经有一个同样的问题提交的bug:https://jira.mongodb.org/browse/SERVER-2193 –

回答

3

还有谁想要这个功能多的人因为没有办法解决这个,我会建议表决插入向上特征请求吉拉门票jira.mongodb.org:

需要注意的是,因为785将提供一种方法来执行此功能,2193被标记为“不会修复”,所以它可能是更富有成效投票起来,自己的意见加入785

+0

是的,我没有在这里收到明确的答案后发现它。我会接受这个,因为虽然upsert是一个可行的选择,但它只是一种替代方案,并不真正模仿所需的行为。 – sashkello

0

唯一性,你可以保证,使用upsert操作,而不是做插入。这将确保,如果某些文件已经存在,那么它会更新,或者如果文件不存在

test:Mongo > db.test4.ensureIndex({ a : 1, b : 1, c : 1}, {sparse : 1}) 

test:Mongo > db.test4.update({a : 1, b : 1}, {$set : { d : 1}}, true, false) 
test:Mongo > db.test4.find() 
{ "_id" : ObjectId("51ae978960d5a3436edbaf7d"), "a" : 1, "b" : 1, "d" : 1 } 
test:Mongo > db.test4.update({a : 1, b : 1, c : 1}, {$set : { d : 1}}, true, false) 
test:Mongo > db.test4.find() 
{ "_id" : ObjectId("51ae978960d5a3436edbaf7d"), "a" : 1, "b" : 1, "d" : 1 } 
{ "_id" : ObjectId("51ae97b960d5a3436edbaf7e"), "a" : 1, "b" : 1, "c" : 1, "d" : 1 } 
+0

这是倒退。如果所有三个字段都不存在,他希望允许重复。如果只有三个字段中的两个出现,使用upserts将防止重复 - 此外,这会显着复杂逻辑,因为每个插入需要检查要插入的文档,以确定三个字段中的哪一个存在以进行更新。另外当你想对文档的不同属性做一个真正的upsert时会发生什么? –

+0

如果所有三个键都存在于文档中(插入),则可以通过执行upserts(而不是插入)来轻松解决此问题,我想这很容易从应用程序中检查。休息我从来没有谈论过这个表演。但考虑到这些字段的索引不会是一个巨大的性能问题,因为在正常的插入中也会更新索引,因此必须将其带入内存。这个解决方案只是建议作为解决方法。 –

+0

当你需要根据不同的值做一个upsert时会发生什么 - 比如说基于用户名或id或者...? –