2011-08-25 16 views
8

La documentación de mongo establece que "Cuando un documento se guarda en una colección con índices únicos, cualquier clave indexada que falte se insertará con valores nulos. Por lo tanto, no será posible insertar varios documentos sin la misma clave indexada".¿Cómo se consiguen los valores perdidos en un índice único con mongo db?

Entonces, ¿es imposible crear un índice único en un campo opcional? ¿Debo crear un índice compuesto con decir un userId también para resolver esto? En mi caso específico, tengo una colección de usuarios que tiene un objeto oauth incorporado opcional. p.

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

Mi usuario de ejemplo

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

Respuesta

11

yo creo que esto es posible: Puede tener un índice que es escasa y única. De esta forma, los valores inexistentes nunca llegan al índice, por lo tanto, no pueden duplicarse.

Advertencia: Esto no es posible con los índices compuestos. No estoy muy seguro de tu pregunta. Usted cita una parte de la documentación que se refiere a índices compuestos: allí, se insertarán los valores faltantes, pero de su pregunta, ¿supongo que no está buscando una solución con índices compuestos?

He aquí una muestra:

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

También tenga en cuenta que compound indexes can't be sparse

+1

Bueno, incluso está documentado: "Puede combinar disperso con exclusivo para producir una restricción única que ignora documentos con campos faltantes". – MrKurt

+0

otra pregunta, si no puede tener índices compuestos dispersos, ¿puede tener un índice disperso en un objeto incrustado o en un campo anidado? En el ejemplo anterior, nos gustaría tener un índice en la colección embebida de oauthConnections. – MonkeyBonkey

2

No es imposible para indexar un campo opcional. Los documentos están hablando de un único índice. Una vez que haya especificado un índice único, solo puede insertar un documento por valor para ese campo, incluso si ese valor es nulo.

Si quiere un índice único en un campo opcional pero todavía permite nulos múltiples, podría tratar de hacer que el índice sea único y escaso, aunque no tengo idea de si eso es posible. No pude encontrar una respuesta en la documentación.

+0

sip, que debería haber sido más específico al decir que quería crear un índice único en un campo opcional. – MonkeyBonkey

1

No hay una buena manera de indexar de forma exclusiva un campo opcional. Puede llenarlo con un valor predeterminado (el _id en el usuario funcionaría), permita que su capa de acceso haga cumplir la singularidad, o cambie su "esquema" un poco.

Tenemos una colección separada para los tokens de inicio de sesión oauth, parcialmente por este motivo. Realmente nunca necesitamos acceder a ellos en un contexto donde tenerlos como documentos integrados es una victoria obvia. Si se trata de un cambio relativamente fácil de realizar, probablemente sea la mejor opción.

---- ---- edición

Como los otros puntos de respuestas, se puede lograr esto con un índice disperso. Incluso es un uso documentado. Probablemente deberías aceptar una de esas respuestas en lugar de la mía.

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

Cuestiones relacionadas