请耐心等待,我对整个CouchDb的东西都很陌生。
db看起来像:
** item ** count ** user **
A 20 bob
B 30 bob
C 10 bob
D 15 john
我想写一个MapReduce,它选择属于bob的所有项目,只返回前2个,排序。所以它应该返回[{item:"B",count:"30"},{item:"A",count:"20}]
我不确定如何做到这一点?好像我必须发出(doc.item,doc.count),但我怎么知道用户是否拥有该文档?如何运行另一个MapReduce来选择顶部元素?
答案 0 :(得分:2)
一种解决方案是编写视图以使用复杂的密钥,例如:
function (doc) {
emit([doc.user, doc.count], doc.item);
}
如果您在查询字符串中添加descending=true
,那么会为您提供如下结果:
{"total_rows":4,"offset":0,"rows":[
{"id":"53f359b7cd360da296dd9aab3d0029bd","key":["john",15],"value":"D"},
{"id":"53f359b7cd360da296dd9aab3d001a0e","key":["bob",30],"value":"B"},
{"id":"53f359b7cd360da296dd9aab3d000fec","key":["bob",20],"value":"A"},
{"id":"53f359b7cd360da296dd9aab3d002668","key":["bob",10],"value":"C"}
]}
它已由用户排序,然后计数。 (项目类型为值)
然后您可以使用_list
function来完成剩下的工作。下面的代码基本上循环遍历视图,并返回每个用户的前2个结果。如果您在查询字符串中指定user=bob
,则只会获得bob
的结果。
function (head, req) {
// specify that we're sending JSON as our response
provides('json', function () {
var results = [],
result, user, count, row;
while (row = getRow()) {
// if the user doesn't match the last iteration, reset our counter
if (user != row.key[0]) {
user = row.key[0];
count = 0;
}
// we only need the top 2
if (count++ >= 2) {
continue;
}
// start building a result object
result = {
item: row.value,
count: row.key[1]
};
// if we provide user=?
if (req.query.user) {
// check to see if it matches the current user
if (req.query.user === user) {
// if so, add it to the results
results.push(result);
}
// by default, we'll return the top 2 for every user
} else {
// add the user key to the result object
result.user = row.key[0];
// and add it to the result set
results.push(result);
}
}
// send outside the loop, since it needs to be sent as valid JSON
send(JSON.stringify(results));
});
}
答案 1 :(得分:2)
如果您将user
和count
放入视图的键中,则可以使用startkey=["bob",""]
和endkey=["bob"]
来选择用户,descending=true
和limit=2
获得前两项。
我尝试了以下地图功能:
function(doc) {
if(doc.user && doc.count && doc.item) {
emit([doc.user, doc.count], doc);
}
}
使用查询字符串?startkey=["bob",""]&endkey=["bob"]&descending=true&limit=2
返回:
{"total_rows":4,"offset":1,"rows":[
{"id":"item_B_bob","key":["bob",30],"value":{"_id":"item_B_bob","_rev":"1-b23bd22fb719c7d59b045bce0932df8c","item":"B","count":30,"user":"bob"}},
{"id":"item_A_bob","key":["bob",20],"value":{"_id":"item_A_bob","_rev":"2-515bca46eab383cfeaaa2a101d180291","item":"A","count":20,"user":"bob"}}
]}
请注意:
startkey
和endkey
被撤销because descending=true
。["bob",""]
是比view collation中指定的["bob", ANY NUMBER]
更大的密钥。