所以我不认为有一个解决方案可以完全在 CouchDB 中完成,它会为学生、科目配对检索单个值。但是,可以创建一个 map/reduce 视图,它几乎可以生成您正在寻找的内容。然后可以使用该视图的结果来查找学生、科目对的排名。
我们首先使用与 joscas 建议的地图非常相似的地图构建视图。唯一的区别是主题名称不是硬编码的:
地图.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);
}
我们将它与一个 reduce 函数配对,该函数将为给定 agroup=true
和grouping_level=1
减少.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;
}
数据
我在数据集中添加了第三个学生,并创建了一些联系以使其变得有趣。这是使用的数据:
{
"_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(或其他客户端技术)搜索生成的词典,以确定学生在单个(或所有)科目中的排名。