简体   繁体   English

如何使用mongo db解决唯一索引中的缺失值?

[英]How do you get around missing values in a unique index using mongo db?

The mongo documentation states that "When a document is saved to a collection with unique indexes, any missing indexed keys will be inserted with null values. Thus, it won't be possible to insert multiple documents missing the same indexed key." mongo文档声明“当文档保存到具有唯一索引的集合时,任何丢失的索引键都将插入空值。因此,将无法插入缺少相同索引键的多个文档。”

So is it impossible to create a unique index on an optional field? 那么在可选字段上创建唯一索引是不可能的吗? Should I create a compound index with say a userId as well to solve this? 我应该用userId创建一个复合索引来解决这个问题吗? In my specific case I have a user collection that has an optional embedded oauth object. 在我的特定情况下,我有一个具有可选嵌入式oauth对象的用户集合。 eg 例如

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

My sample user 我的示例用户

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

I believe that this is possible: You can have an index that is sparse and unique . 我相信这是可能的:您可以拥有一个稀疏且唯一的索引。 This way, non-existant values never make it to the index, hence they can't be duplicate. 这样,不存在的值永远不会进入索引,因此它们不能重复。

Caveat : This is not possible with compound indexes. 警告 :复合索引无法做到这一点。 I'm not quite sure about your question. 我不太确定你的问题。 Your citing a part of the documentation that concerns compound indexes -- there, missing values will be inserted, but from your question I guess you're not looking for a solution w/ compound indexes? 您引用了涉及复合索引的文档的一部分 - 那里将插入缺失值,但是从您的问题我猜你不是在寻找具有复合索引的解决方案?

Here's a sample: 这是一个示例:

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

Also note that compound indexes can't be sparse 另请注意, 复合索引不能稀疏

It is not impossible to index an optional field. 索引可选字段并非不可能。 The docs are talking about a unique index. 文档正在谈论一个独特的索引。 Once you've specified a unique index, you can only insert one document per value for that field, even if that value is null. 一旦指定了唯一索引,即使该值为null,也只能为该字段的每个值插入一个文档。

If you want a unique index on an optional field but still allow multiple nulls, you could try making the index both unique and sparse, although I have no idea if that's possible. 如果你想在可选字段上使用唯一索引但仍然允许多个空值,你可以尝试使索引既独特又稀疏,尽管我不知道是否可能。 I couldn't find an answer in the documentation. 我在文档中找不到答案。

There's no good way to uniquely index an optional field. 没有好的方法来唯一索引可选字段。 You can either fill it with a default (the _id on the user would work), let your access layer enforce uniqueness, or change your "schema" a bit. 您可以使用默认值填充它(用户的_id将起作用),让您的访问层强制执行唯一性,或稍微更改“架构”。

We have a separate collection for oauth login tokens, partially for this reason. 由于这个原因,我们有一个单独的oauth登录令牌集合。 We never really need to access those in a context where having them as embedded docs is an obvious win. 我们从来没有真正需要访问那些将它们作为嵌入式文档显然获胜的环境。 If this is a relatively easy change to make, it's probably your best bet. 如果这是一个相对容易的改变,那可能是你最好的选择。

----edit---- - - 编辑 - -

As the other answers points, you can achieve this with a sparse index. 正如其他答案所指出的那样,您可以使用稀疏索引实现此目的。 It's even a documented use. 它甚至是有记录的用途。 You should probably accept one of those answers instead of mine. 您应该接受其中一个而不是我的答案。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM