2011-08-25 20 views
8

mongo文档指出:“当文档被保存到具有唯一索引的集合中时,任何缺少索引的键将被插入空值,因此,不可能插入多个缺少相同索引键的文档。如何避免在使用mongo db的唯一索引中丢失值?

因此,不可能在可选字段上创建唯一索引?我应该用一个userId创建一个复合索引来解决这个问题吗?在我的具体情况中,我有一个拥有可选嵌入式oauth对象的用户集合。 例如

>db.users.ensureIndex({ "name":1, "oauthConnections.provider" : 1, "oauthConnections.providerId" : 1 }); 

我的示例用户

{ name: "Bob" 
    ,pwd: "myPwd" 
    ,oauthConnections [ 
     { 
     "provider":"Facebook", 
     "providerId" : "12345", 
     "key":"blah" 
     } 
    ,{ 
     "provider":"Twitter", 
     "providerId" : "67890", 
     "key":"foo" 
     } 
    ] 
} 

回答

11

我认为这是可能的:你可以有一个指标是稀疏和独特。这样,不存在的值永远不会对索引产生影响,因此它们不能重复。

警告:这对于复合索引是不可能的。我不太清楚你的问题。你引用了涉及复合索引的文档的一部分 - 在那里,将会插入缺失的值,但是从你的问题我猜你没有找到一个解决方案W /复合索引?

这里有一个例子:

> db.Test.insert({"myId" : "1234", "string": "foo"}); 
> show collections 
Test 
system.indexes 
> 
> db.Test.find(); 
{ "_id" : ObjectId("4e56e5260c191958ad9c7cb1"), "myId" : "1234", "string" : "foo" } 
> 

> db.Test.ensureIndex({"myId" : 1}, {sparse: true, unique: true}); 
> 
> db.Test.insert({"myId" : "1234", "string": "Bla"}); 
E11000 duplicate key error index: test.Test.$myId_1 dup key: { : "1234" } 
> 
> db.Test.insert({"string": "Foo"}); 
> db.Test.insert({"string": "Bar"}); 
> db.Test.find(); 
{ "_id" : ObjectId("4e56e5260c191958ad9c7cb1"), "myId" : "1234", "string" : "foo" } 
{ "_id" : ObjectId("4e56e5c30c191958ad9c7cb4"), "string" : "Foo" } 
{ "_id" : ObjectId("4e56e5c70c191958ad9c7cb5"), "string" : "Bar" } 

还要注意的是compound indexes can't be sparse

+1

不错,甚至有文件记录:“您可以将稀疏与独特相结合,以产生一个独特的约束,忽略缺少字段的文档。” – MrKurt

+0

另一个问题,如果你不能有稀疏的复合索引,你可以有一个嵌入式对象或嵌套字段的稀疏索引?在上面的例子中,我们希望在嵌入的oauthConnections集合上有一个索引。 – MonkeyBonkey

2

这不是不可能的索引可选字段。该文档正在讨论一个独特的索引。一旦指定了唯一索引,即使该值为空,也只能为该字段的每个值插入一个文档。

如果您想在可选字段上使用唯一索引,但仍然允许多个空值,您可以尝试使索引既是唯一的也是稀疏的,尽管我不知道这是否可能。我无法在文档中找到答案。

+0

烨,我应该在说,我想创建一个可选字段唯一索引更具体。 – MonkeyBonkey

1

有没有好办法唯一索引可选字段。您可以使用默认值(用户的_id可以工作)填充它,让您的访问层强制唯一性,或者更改您的“架构”。

我们有一个单独的oauth登录令牌集合,部分出于这个原因。我们从来没有真正需要访问那些在嵌入式文档中获得明显胜利的环境。如果这是一个相对容易的改变,那可能是你最好的选择。

---- ----编辑

至于其他的答案点,你可以用一个稀疏索引实现这一目标。它甚至是一个记录的使用。你应该接受这些答案中的一个,而不是我的答案。

http://www.mongodb.org/display/DOCS/Indexes#Indexes-SparseIndexes

相关问题