Mongodb 如何使用mongo db绕过唯一索引中缺少的值?

Mongodb 如何使用mongo db绕过唯一索引中缺少的值?,mongodb,Mongodb,mongo文档声明“当文档保存到具有唯一索引的集合时,任何缺少的索引键都将以空值插入。因此,无法插入缺少同一索引键的多个文档。” 那么,在可选字段上创建唯一索引是不可能的吗?我应该创建一个复合索引,比如说一个用户ID来解决这个问题吗?在我的特定情况下,我有一个用户集合,它有一个可选的嵌入oauth对象。 e、 g 我的示例用户 { name: "Bob" ,pwd: "myPwd" ,oauthConnections [ { "provider":"F

mongo文档声明“当文档保存到具有唯一索引的集合时,任何缺少的索引键都将以空值插入。因此,无法插入缺少同一索引键的多个文档。”

那么,在可选字段上创建唯一索引是不可能的吗?我应该创建一个复合索引,比如说一个用户ID来解决这个问题吗?在我的特定情况下,我有一个用户集合,它有一个可选的嵌入oauth对象。 e、 g

我的示例用户

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

为可选字段编制索引并非不可能。文档正在讨论一个唯一的索引。一旦指定了唯一索引,即使该字段的值为null,每个值也只能插入一个文档


如果您希望在可选字段上有一个唯一的索引,但仍然允许多个null,那么可以尝试使索引既唯一又稀疏,尽管我不知道这是否可行。我在文档中找不到答案。

没有唯一索引可选字段的好方法。您可以用默认值填充它(用户上的_id可以使用),让您的访问层强制唯一性,或者稍微更改您的“模式”

我们有一个单独的oauth登录令牌集合,部分是出于这个原因。在将它们作为嵌入式文档显然是一种胜利的情况下,我们永远不需要访问它们。如果这是一个相对容易的改变,它可能是你最好的选择

----编辑----

正如其他答案所指出的,您可以通过稀疏索引来实现这一点。这甚至是一个记录在案的使用。你应该接受其中一个答案,而不是我的


我相信这是可能的:您可以拥有一个稀疏且唯一的索引。这样,不存在的值就不会到达索引,因此它们不能重复

警告:这在复合索引中是不可能的。我不太确定你的问题。您引用了文档中涉及复合索引的一部分——在这里,将插入缺少的值,但从您的问题来看,我猜您不是在寻找一个包含复合索引的解决方案

以下是一个示例:

> 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" }

还请注意

是的,我应该更具体地说,我想在一个可选字段上创建一个唯一索引。很好,它甚至有文档记录:“你可以将稀疏和唯一结合起来,生成一个唯一约束,忽略缺少字段的文档。”另一个问题,如果你不能使用稀疏复合索引,可以在嵌入对象或嵌套字段上使用稀疏索引吗?在上面的示例中,我们希望在嵌入的oauthConnections集合上有一个索引。
> 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" }