したがって、CouchDBで完全に実行できるソリューションはないと思います。このソリューションでは、学生とサブジェクトのペアリングに対して単一の値を取得します。ただし、探しているものにほぼ近いマップ/リデュースビューを作成できます。次に、そのビューの結果を使用して、学生と被験者のペアのランクを見つけることができます。
まず、joscasによって提案されたものと非常によく似たマップを使用してビューを作成します。唯一の違いは、サブジェクト名がハードコーディングされていないことです。
map.js
function(doc) {
var total = 0;
for (var subject in doc.score) {
var score = doc.score[subject];
emit([subject, score], doc.student_name);
total += score;
}
emit(["total", total], doc.student_name);
}
group=true
これをreduce関数と組み合わせて、aとを与えられた各サブジェクトのランキングを生成します。grouping_level=1
reduce.js
function(keys, values) {
var rankings = {}; // In order to return ties, a simple array can't be used.
var rank = 0;
var place = 0;
var last_score = -1;
for (var i = 0; i < values.length; i++) {
var name = values[i];
var score = keys[i][0][1]; // The 0th element of the key is the [subject, score] array.
if (score == last_score) {
// Tie, add another student to this rank.
place++;
} else {
// Not a tie, create a new rank.
rank += (place + 1);
rankings[rank] = new Array();
place = 0;
last_score = score;
}
rankings[rank][place] = name;
}
return rankings;
}
データ
データセットに3人目の生徒を追加し、それを面白くするためにいくつかの関係を作成しました。使用したデータは次のとおりです。
{
"_id": "ce6b2cd97e73258014679ab7bb9e7cdc",
"_rev": "2-b62581d22c186bfc8ebe1703a2dfb506",
"score": {
"chemistry": 60,
"math": 90,
"physics": 88
},
"student_name": "Mike"
}
{
"_id": "ce6b2cd97e73258014679ab7bb9e8ada",
"_rev": "5-94d6cfbd3cf22f903ebc306570d1f1af",
"score": {
"chemistry": 90,
"math": 90,
"physics": 98
},
"student_name": "Jane"
}
{
"_id": "ce6b2cd97e73258014679ab7bb9e960b",
"_rev": "1-d8c7fe88de63cf3d6e9743696f96aad0",
"score": {
"chemistry": 61,
"math": 89,
"physics": 88
},
"student_name":
"Charlie"
}
結果
ビューはランクとして保存され、次のようにクエリできます。
http://127.0.0.1:5984/atest/_design/atest/_view/rank?group=true&group_level=1
これにより、次の結果が得られます。
{
"rows":[
{"key":["chemistry"],"value":{"1":["Jane"],"2":["Charlie"],"3":["Mike"]}},
{"key":["math"],"value":{"1":["Jane","Mike"],"3":["Charlie"]}},
{"key":["physics"],"value":{"1":["Jane"],"2":["Charlie","Mike"]}},
{"key":["total"],"value":{"1":["Jane"],"2":["Charlie","Mike"]}}
]
}
ビューは、次のようにサブジェクトによってクエリできます(最低スコアが0で、最高スコアが100であると想定)。
http://127.0.0.1:5984/atest/_design/atest/_view/rank?group=true&group_level=1&startkey=%5B%22math%22,0%5D&endkey=%5B%22math%22,100%5D
(URLエンコードなし):
http://127.0.0.1:5984/atest/_design/atest/_view/rank?group=true&group_level=1&startkey=["math",0]&endkey=["math",100]
これにより、次の結果が得られます。
{
"rows":[
{"key":["math"],"value":{"1":["Jane","Mike"],"3":["Charlie"]}}
]
}
結果の辞書は、Javascript(または他のクライアント側テクノロジー)を使用して検索し、単一(またはすべて)の科目での学生のランクを決定できます。