2011-04-12 9 views
2

Donc, je suis assez nouveau à mongoDb donc je pense que cela pourrait être un malentendu sur l'utilisation générale. alors sois indulgent avec moi. J'ai un schéma de document, je travaille comme telmongoDB: index unique sur une valeur répétée

{ 
    name: "bob", 
    email: "[email protected]", 
    logins: [ 
     { u: 'a', p: 'b', public_id: '123' }, 
     { u: 'x', p: 'y', public_id: 'abc' } 
    ] 
    } 

Mon problème est que je dois veiller à ce que les ids publics sont uniques dans un document et de collecte, De plus il y a des enregistrements existants en cours de migration de une base de données MySQL qui n'a pas d'enregistrements, et sera donc remplacée par des valeurs null dans mongo.

je me dis que son soit un indice

db.users.ensureIndex({logins.public_id: 1}, {unique: true}); 

qui ne fonctionne pas à cause des clés manquantes et jette un E11000 duplicate key error index:

ou c'est un problème de schéma plus fondamental que je ne devrais pas soit imbriquer des objets dans une structure de tableau comme ça. Dans quel cas, quoi? une collection séparée pour les user_logins ??? ce qui semble aller à l'encontre de l'idée d'un document incorporé.

Répondre

0

Merci à tous. Finalement, j'ai choisi de séparer cela en 2 collections, une pour les utilisateurs et une pour les connexions. utilisateurs ça avait l'air un peu comme ..

userDocument = { 
     ... 
     logins: [ 
     DBRef('loginsCollection', loginDocument._id), 
     DBRef('loginsCollection', loginDocument2._id),  
     ] 
    } 

    loginDocument = { 
     ... 
     user: new DBRef('userCollection', userDocument ._id) 
    } 

Bien que pas ce que j'était à l'origine après (une seule collection) Il travaille niocely et en utilisant le MongoId uniquness il y a une contrainte maintenant construit en à un niveau de base de données et pas implémenté au niveau de l'application.

2

Si vous vous attendez u et p toujours avoir les mêmes valeurs sur chaque insert (comme dans votre exemple extrait), vous pouvez utiliser l'opérateur $addToSet sur des inserts pour assurer l'unicité de votre champ public_id. Sinon, je pense qu'il est assez difficile de les rendre uniques sur une collection entière ne fonctionnant pas avec la maintenance externe ou les fonctions js. Si ce n'est pas le cas, je les stockerais peut-être dans leur propre collection et j'utiliserais le champ public_id comme _id pour assurer leur unicité de documents croisés à l'intérieur d'une collection. Peut-être que cela contredirait l'idée de documents intégrés dans une base de données de doc, mais selon des exigences différentes, je pense que c'est négligeable.

+0

Malheureusement, je me trompe. [corrigé], j'ai besoin de cela pour travailler sur les insertions et les mises à jour. Je pense que $ addToSet ne fonctionnera qu'avec les mises à jour. En outre, il doit être implémenté par requête plutôt que comme une contrainte de base de données. – Roon

+0

@Roon: lire sur 'upsert': http: //www.mongodb.org/display/DOCS/Mise à jour –

+0

L'utilisation de la condition upsert impliquerait également de faire des mises à jour, ce qui pourrait être utile pour vérifier si public_id existe déjà dans les docs imbriqués en cas de différences entre u et p. Je pense qu'il n'y a pas de solution sauf de stocker les docs imbriqués dans leur propre collection et en utilisant le champ _id ou un index alternatif pour implémenter la restriction en tant que contrainte db. – proximus

1

De plus, certains enregistrements existants migrent à partir d'une base de données mySQL qui n'a pas d'enregistrements et seront donc tous remplacés par des valeurs nulles dans mongo.

Vous souhaitez donc appliquer un index unique à un ensemble de données qui n'est pas vraiment unique. Je pense que c'est juste un problème de modélisation.

Si logins.public_id est null qui va violer votre contrainte d'unicité, alors il suffit de ne pas écrire du tout:

{ 
    logins: [ 
     { u: 'a', p: 'b' }, 
     { u: 'x', p: 'y' } 
    ] 
    }