2010-12-10 7 views
0

Ich habe Probleme zu versuchen, meinen Kopf bekommen, um eine Sammlung von Typen zusammen mit der Häufigkeit, wie eine Fähigkeit in diesem Dokumenttyp gefunden wird.couchdb - Probleme Gruppierung von Sammlungen

Es gibt eine Reihe von Dokumenttypen mit einer Liste von Fähigkeiten.


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

{ 
    "skills": "Ruby, Rails, Erlang", 
    "type": "Project" 
} 

Ich versuche zu erhalten, wie oft eine Fähigkeit in einem Dokumententyp gefunden wird.

Das Endergebnis sollte wie folgt aussehen:



{ 
    '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} 
    ] 
} 

Was wäre der beste Weg, dies zu tun?

Antwort

0

Hier werden Karte und reduzieren Funktionen (Ansicht mit dem Namen skill_split) und eine Liste Funktion, die Ausgabe erzeugen wird in der Nähe zu dem, was Sie dieses http://127.0.0.1:5984/myskills/_design/myskills/_list/transform/skill_split?group=true für die Verwendung einer URL gefragt:

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

Ich kann den Code optimieren zu machen die Ausgabe genau das, wonach Sie gefragt haben, aber die Listenfunktion wäre etwas länger.

Karte:

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

reduzieren:

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

oder "reduce": "_sum" kurz verwenden für

Liste (benannt transform):

Wenn Sie keinen Zugriff auf das JSON-Objekt haben (Sie tun dies in einer CouchApp), müssen Sie möglicherweise durch einige Rahmen springen, um Zugriff darauf zu erhalten.

+0

Danke, das scheint die nächste Lösung für mein Problem zu sein: D – baphled

+0

Toll, froh, dass ich helfen konnte. :) –

1

Sie sollten die Skill-Liste in Ihren Dokumenten als eine echte Liste speichern.

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

Von dort Ihre Kartenfunktion wird:

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

Und die Verringerung Funktion fasst nur das Ergebnis, so verwenden "_sum". Sie können einfach auswählen, dass nur Experience oder Project mit Start- und Endtasten angezeigt werden.

+0

Ich hatte zuvor eine ähnliche Lösung, aber es löste nicht das Problem, dass ich nicht feststellen konnte, dass in irgendwelchen Erlebniseinträgen keine Ruby-Fähigkeiten zu finden sind. Die obige Struktur wird benötigt, damit ich Graphen darstellen kann. – baphled

+0

Cygals Lösung lässt Sie feststellen, dass keine Ruby-Skills in irgendwelchen Erlebniseinträgen gefunden werden, denn wenn Sie die Ansicht für den Schlüssel '[" Experience "," Ruby "] abfragen, erhalten Sie keine Ergebnisse. –

+0

Wahr, aber für dieses spezielle Problem muss ich die gleiche Menge an Fähigkeiten in jedem Eintrag zusammen mit der Zählung haben. Die Daten werden an ein Diagramm übergeben, das erwartet, dass in jedem Eintrag die gleiche Anzahl an Ergebnissen und Werten vorhanden ist. Ich kann das mit einigem jQuery hacken, aber ich möchte diese Funktionalität sonst wo verwenden und die Datenmanipulation eher nicht duplizieren. – baphled