【问题标题】:How do you get around missing values in a unique index using mongo db?如何使用 mongodb 解决唯一索引中的缺失值?
【发布时间】:2011-11-03 16:12:23
【问题描述】:

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

那么在可选字段上创建唯一索引是不可能的吗?我是否应该创建一个带有 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"
      }
     ]
}

【问题讨论】:

    标签: mongodb


    【解决方案1】:

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

    警告:这对于复合索引是不可能的。我不太确定你的问题。您引用了有关复合索引的文档的一部分-在那里,将插入缺失值,但是从您的问题来看,我猜您不是在寻找带有复合索引的解决方案?

    这是一个示例:

    > 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

    【讨论】:

    • 很好,它甚至被记录在案:“您可以将 sparse 与 unique 结合起来产生一个唯一约束,该约束会忽略缺少字段的文档。”
    • 另一个问题,如果你不能有稀疏复合索引,你能在嵌入对象或嵌套字段上有稀疏索引吗?在上面的示例中,我们希望在嵌入的 oauthConnections 集合上有一个索引。
    【解决方案2】:

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

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

    【讨论】:

    • 是的,我应该更具体地说明我想在可选字段上创建唯一索引。
    【解决方案3】:

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

    我们有一个单独的 oauth 登录令牌集合,部分原因是出于这个原因。我们永远不需要在将它们作为嵌入式文档的上下文中访问它们是一个明显的胜利。如果这是一个相对容易进行的更改,那么它可能是您最好的选择。

    ----编辑----

    作为其他答案点,您可以使用稀疏索引来实现这一点。它甚至是一个有记录的用途。您可能应该接受其中一个答案而不是我的答案。

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

    【讨论】:

      猜你喜欢
      • 2014-09-12
      • 1970-01-01
      • 2020-10-09
      • 1970-01-01
      • 1970-01-01
      • 2016-10-28
      • 1970-01-01
      • 1970-01-01
      • 2020-07-26
      相关资源
      最近更新 更多