2012-04-29 7 views
1

Je construis un système d'utilisateurs très simple sur Apache CouchDB. Je construire une simple vue de rechercher les utilisateurs par email:CouchDB Simple SELECT dans le bon sens?

by_email 
map 
function(doc) { 
if (doc.kind == "user" && doc.email) emit(doc.email, doc.name); 
} 

ce retour

{"id"=>"00006a80-723b-012f-6b38-1040f398478e", "key"=>"[email protected]", "value"=>"Spiderman"} 

Maintenant, je pourrais être absent quelque chose de très stupide (si tel est le cas je fais, je présente mes excuses), mais pourquoi vous peut seulement récupérer 2 champs (3 si nous comptons l'ID) de cette vue? Comme dans une situation normale, vous pouvez rechercher dans la base de données de vos utilisateurs à partir de l'e-mail ou de l'ID utilisateur et récupérer le document complet.

Maintenant, j'ai lu l'exemple à http://guide.couchdb.org/draft/cookbook.html (recherche par clé) et, à moins que je manque quelque chose de très trivial, le résultat est incomplet aussi car il ne renverra que le nom des utilisateurs avec un certain âge et rien plus.

Je ne comprends pas comment cela serait d'une bonne utilisation: si vous interrogez votre base de clients, les fournisseurs, tout ce que vous voulez que le document en arrière et non seulement 1 des valeurs ou 2.

donc ma solution était une autre vue:

mailplus 
map 
function(doc) { if (doc.kind == "user" && doc.email) emit(doc.email,doc) } 

ainsi de me renvoyer l'email mais aussi le document complet comme valeur. Cela fonctionne mais comme vous pouvez l'imaginer, il est considérablement plus lent dans une base de données plus grande. La question est donc la suivante: y a-t-il une meilleure façon de faire une requête simple pour récupérer des détails complets sur un utilisateur effectuant une recherche par email en utilisant par exemple CouchDB - NoSQL?

Je sais que la tentation de répondre "c'est faux car on ne peut pas penser SQL en NoSQL" mais attendez: dans une application du monde réel, pensant NoSQL en termes de Documents et non tables/lignes etc, vous pourriez voulez le document complet pour un utilisateur. Imaginez que vous ayez un système simple pour récupérer les détails du client. Vous avez besoin du document complet. Vous n'avez pas besoin de connaître l'identifiant et la clé seulement lorsque vous fournissez la clé, email, en premier lieu.

Répondre

3

Cela fait un moment que j'ai utilisé couchdb mais je crois que c'est toujours exact.

Vous ne pouvez récupérer que ces 2 champs parce que c'est tout ce que vous avez mis dans la vue. En interne, couchdb suit l'identifiant du document correspondant à chaque clé/valeur émise. Vous pouvez ensuite utiliser l'option include_docs lors de l'interrogation ce point de vue d'avoir CouchDB rechercher les documents par identifiant (voir le docs)

L'autre choix que vous avez décrit est d'avoir le document en vue, qui fera beaucoup plus l'indice

+0

donc une solution possible est d'utiliser par exemple l'email comme identifiant (ou le nom d'utilisateur)? Cela imposerait des utilisateurs uniques (malgré la limitation de la réplication), ce qui constitue un autre problème. Honnêtement, je pense qu'il me manque quelque chose: ne valide pas un enregistrement (validates_uniqueness_of: email,: nom d'utilisateur) quelque chose de relativement basique et attendu dans le développement web? Comme il récupère un profil complet pour un utilisateur e.g. Lorsque l'utilisateur veut modifier ses détails – devnull

+0

pour une telle validation d'unicité, vous pouvez émettre deux fois pour chaque document, d'abord avec l'email comme clé et ensuite avec le nom, après cette vérification pour voir apparaître deux clés (voir le wiki couchdb) . mais cela ne résoudra pas le problème car quelqu'un pourrait insérer l'enregistrement après votre vérification, en outre en cas de réplication il est possible d'insérer une clé en conflit sur différents serveurs, comment résoudre le conflit? la bonne résolution devrait utiliser des contraintes de base de données comme mysql, afair rails ne les utilise pas dans leur activeecord. couchdb a des valideurs côté serveur mais vous ne pouvez pas faire de sous-requête – avsej

2

Vous n'avez pas besoin d'émettre le document. Ajoutez simplement include_docs=true à vos paramètres de requête. Les documents complets sont sur le wiki 1.

1

vous pouvez également émettre une partie du document EMIT (doc.email, {nom: doc.name, age: doc.age})

Questions connexes