2010-12-10 4 views
0

J'ai des problèmes pour essayer de trouver une collection de types avec le nombre de fois qu'une compétence est trouvée dans ce type de document.couchdb - problèmes de regroupement des collections

Il existe un certain nombre de types de document qui ont une liste de compétences. J'essaie d'obtenir le nombre de fois qu'une compétence est trouvée dans un type de document.

Le résultat final devrait ressembler à ceci:



{ 
    'type': Experience, 
    'skills': [ 
    {'skill': 'Erlang', 'count': 1}, 
    {'skill': 'Linux', 'count': 2}, 
    {'skill': 'Network Admin', 'count': 1}, 
    {'skill': 'Rails', 'count': 0}, 
    {'skill': 'Ruby', 'count': 0}, 
    {'skill': 'Windows', 'count': 2} 
    ] 
}, 
{ 
    'type': Project, 
    'skills': [ 
    {'skill': 'Erlang', 'count': 1}, 
    {'skill': 'Linux', 'count': 0}, 
    {'skill': 'Network Admin', 'count': 0}, 
    {'skill': 'Rails', 'count': 1}, 
    {'skill': 'Ruby', 'count': 1}, 
    {'skill': 'Windows', 'count': 0} 
    ] 
} 

Quelle serait la meilleure façon de le faire?

Répondre

0

Voici la carte et réduis fonctions (voir le nom skill_split) et une fonction de liste qui produira une sortie proche de ce que vous avez demandé l'aide d'une URL comme celui-ci http://127.0.0.1:5984/myskills/_design/myskills/_list/transform/skill_split?group=true:

{ 
    "Experience": {"Erlang":1, "Linux":2, "Network Admin":1, "Windows":2}, 
    "Project":{"Erlang":1, "Rails":1, "Ruby":1} 
} 

Je peux modifier le code pour faire la sortie exactement ce que vous avez demandé, mais la fonction de liste serait un peu plus longue.

carte:

function(doc) { 
    if (doc.type && doc.skills) { 
    doc.skills.split(', ').forEach(function(skill) { 
     emit([doc.type, skill], 1); 
    }); 
    } 
} 

réduire:

function(keys, values, rereduce) { 
    return sum(values) 
} 

ou utiliser "reduce": "_sum" pour court

liste (nom transform):

function(head, req) { 
    var results = {}; 
    var row; 
    while (row = getRow()) { 
    var skill_map; 
    if (results.hasOwnProperty(row.key[0])) { 
     skill_map = results[row.key[0]]; 
    } else { 
     skill_map = {}; 
     results[row.key[0]] = skill_map; 
    } 

    if (skill_map.hasOwnProperty(row.key[1])) { 
     skill_map[row.key[1]] = skill_map[row.key[1]] + row.value; 
    } else { 
     skill_map[row.key[1]] = row.value; 
    } 
    } 
    send(JSON.stringify(results)); 
} 

Si vous le faites, vous pourriez pas avoir accès à l'objet JSON (vous faites dans un couchapp) de sauter à travers quelques cerceaux pour y avoir accès.

+0

Merci, cela semble être la solution la plus proche de mon problème: D – baphled

+0

Super, content que je puisse vous aider. :) –

1

Vous devez stocker la liste des compétences dans vos documents sous forme de liste réelle.

{ 
    "skills": ["Windows", "Network Admin", Linux"], 
    "type": "Experience" 
} 

À partir de là, votre fonction carte devient:

function(doc) { 
    for(var skill in doc.skills) { 
    emit([doc.type, skill], 1); 
    } 
} 

Et la diminution de la fonction résume simplement le résultat, utilisez donc "_sum". Vous pouvez facilement choisir d'afficher uniquement Expérience ou Projet avec les touches de début et de fin.

+0

J'ai déjà eu une solution similaire mais cela n'a pas résolu le problème de ne pas me donner la possibilité de déterminer qu'il n'y a aucune compétence Ruby dans les entrées d'expérience. La structure ci-dessus est nécessaire pour que je puisse rendre des graphiques. – baphled

+0

La solution de Cygal vous permet de déterminer qu'il n'y a aucune compétence Ruby dans les entrées d'expérience, car lorsque vous interrogez la vue pour la clé '[" Expérience "," Ruby "]' vous n'obtiendrez aucun résultat. –

+0

Vrai mais pour ce problème particulier, je dois avoir le même nombre de compétences dans chaque entrée avec le nombre. Les données sont transmises à un graphique qui s'attend à ce qu'il y ait la même quantité de résultats et de valeurs dans chaque entrée. Je peux pirater avec un peu de jQuery mais je veux utiliser cette fonctionnalité ailleurs et ne pas dupliquer la manipulation de données. – baphled

Questions connexes