2014-06-25 5 views
1

Dans mon canapé j'ai paires de documents comme celui-ci:CouchDB: des vues et des clés colocalisés

{ 
    _id: "DOCID", 
    type: "Task", 
    info: { k1: "v1", k2: "v2" } 
} 
{ 
    _id: "ANOTHER DOCID", 
    type: "Final", 
    task: "DOCID", 
    author: "Authorname" 
} 

Pour un auteur, plusieurs de ces paires peuvent exister.

J'ai maintenant besoin d'une vue qui me donnera l'information couplée d'une manière, que le author est accompagné du info.

Utiliser la vue colocalisation j'ai créé la vue suivante:

function(doc) { 
    if (doc.doc_type == "Final") 
    emit([doc.task, 0], doc.author); 
    if (doc.doc_type == "Task") 
    emit([doc._id, 1], doc.definition); 
} 

Et j'obtenir des résultats comme ceux-ci:

["153b46415108e95c811e1d4cd018624f", 0] -> "Authorname" 
["153b46415108e95c811e1d4cd018624f", 1] -> { info here } 

d'abord, j'ai utilisé une diminution de la fonction à intégrer à la fois en un seul, mais après le calendrier il, en les regroupant localement est beaucoup plus rapide.

Cependant, la façon dont il est maintenant, je ne peux pas interroger cette vue par le "Authorname". Surtout pas parce que le info ne vient pas avec un Authorname.

Il y a donc des solutions à ce que je pense:

  1. Utilisez une diminution de la fonction avec regroupement et de manipuler la clé il montre l'auteur (je ne sais pas même si la manipulation d'une clé groupée est possible)
  2. Obtenir toutes les lignes, les regrouper localement, et filtrer pour l'auteur que je recherche (probablement trop de surcharge indésirable)
  3. Avoir plusieurs vues et effectuer 2 requêtes. Un pour obtenir les DOCID, puis interroger les DOCID.
  4. Interrogez la vue colloquée intelligemment: incluez l'Authorname dans la clé et le type de requête de manière efficace, mais je ne pense pas non plus que cela soit possible, car une requête pour Authorname exclura le info réel.

Alors, que recommanderiez-vous de faire à ce sujet? Et oui, il y a une raison pour laquelle l'information est séparée (plusieurs Final documents peuvent être liés au même Task document ayant donc les mêmes informations)

Meilleur

Modifier La solution proposée, est- réponds à ma question, mais je suis parti pour utiliser ma vue et regrouper les résultats dans mon code (un Django View) qui s'est avéré très rapide!

Répondre

0

J'ai maintenant besoin d'une vue qui me donnera l'information couplée d'une manière, que l'auteur est accompagné de l'info.

Donc, si je comprends bien les exigences sont

  1. La vue doit être interrogé par le nom de l'auteur. Les résultats doivent être le nom de l'auteur et le document INFO.

bien vos documents sont parfaitement structurés pour soutenir linked document retrieval

Je pense que cette fonction de carte devrait faire

function(doc) { 

if(doc.author){ 
    emit(doc.author,{_id:doc.task}); 

} 

si je fais une recherche avec le include_docs=true est ici le résultat que je reçois

{ 
    total_rows: 1, 
    offset: 0, 
    rows: [ 
    { 
     id: "19ae88d060834dafdea9417384e2db20", 
     key: "Authorname", 
     value: { _id: "DOCID" }, 
     doc: { 
     _id: "DOCID", 
     _rev: "1-d7fe42dd7858238bb2d1112abf24f046", 
     type: "Task", 
     info: { k1: "v1", k2: "v2" } 
     } 
    } 
    ] 
} 

À propos de réduire à partir du couchdb wiki

Une fonction de réduction doit réduire les valeurs d'entrée à une valeur de sortie inférieure. Si vous construisez une structure composite de retour dans votre réduire, ou seulement transformer le champ de valeurs, plutôt que de le résumer, vous pourriez être mauvais usage de cette fonction

Modifier basé sur le commentaire: -

Depuis que le document de travail est trop grand et que vous ne voulez pas aller chercher tout, il y a deux approches que vous pouvez prendre

  1. Intégrer les informations directement dans l'auteur. Puisque tout ce que vous voulez de la tâche est la partie info. Couchdb et d'autres bases de données sans sql encouragent la dénormalisation des données pour en faciliter l'accès. Utilisez list function pour modifier la sortie json volumineuse dans un format qui sera utilisable par vous.

+0

Merci de m'avoir appris à ce sujet! Vous pourriez envisager de corriger votre code d'affichage. Cependant, j'essaye d'éviter d'aller chercher tout le document Task, car il contient beaucoup de données, que je ne veux pas aller chercher, car dans ce cas ce n'est pas utile et lent. Par conséquent, je dois adopter une approche plus compliquée. – enpenax

+0

@ user2033511 pouvez-vous vérifier si la réponse éditée résout votre problème. –

+0

C'est un peu le cas, mais je suis allé maintenant avec une approche d'utiliser ma vue et de filtrer la sortie manuellement, ce qui s'est avéré être 10x plus rapide (dans mon cas). Je vais donc accepter votre réponse, car elle répond effectivement à la question, mais pour mon cas particulier, j'ai trouvé une solution – enpenax

Questions connexes