2010-12-10 43 views
0

我遇到問題,試圖讓我的頭獲得類型的集合以及在該文檔類型中找到技能的次數。couchdb - 問題分組集合

有許多具有技能列表的文檔類型。


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

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

我試圖獲得在文檔類型中找到技能的次數。

最終的結果應該是這個樣子:



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

什麼是做到這一點的最好方法是什麼?

回答

0

這裏有地圖和減少功能(查看名爲skill_split)和列表功能,這將產生輸出接近你問了使用URL這樣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} 
} 

我可以調整代碼,使輸出正是你所要求的,但是列表函數會稍微長一些。

地圖

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

減少

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

或使用"reduce": "_sum"

列表(命名爲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)); 
} 

如果您無權訪問JSON對象(您在CouchApp中執行此操作),則可能需要跳過一些環節才能訪問它。

+0

謝謝,這似乎是我的問題最接近的解決方案:D – baphled 2011-05-23 10:33:16

+0

太好了,很高興我能幫上忙。 :) – 2011-05-23 14:43:16

1

您應該將技能列表作爲真實列表存儲在您的文檔中。

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

從那裏,你的地圖功能就變成了:

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

而減少功能只是總結的結果,所以用 「_sum」。您可以輕鬆選擇僅顯示開始和結束鍵的體驗或項目。

+0

我以前的確有過類似的解決方案,但它並沒有解決不讓我有能力確定在任何體驗條目中找不到Ruby技能的問題。需要上述結構才能呈現圖形。 – baphled 2010-12-11 02:05:51

+0

Cygal的解決方案可以讓您確定在任何體驗條目中都找不到Ruby技能,因爲當您查詢鍵「[」體驗「,」Ruby「]的視圖時,您將得不到任何結果。 – 2010-12-11 20:12:05

+0

確實如此,但對於這個特殊的問題,我需要在計數的每個條目中擁有相同數量的技能。數據被傳遞給一個圖表,期望每個條目中都有相同數量的結果和值。我可以用一些jQuery破解這個,但我想在其他地方使用這個功能,而不是重複數據操作。 – baphled 2010-12-12 11:48:43