Couchbase/CouchDB按键的一部分分组并按另一部分排序
我有一个用户间信息的数据库。文档看起来像:Couchbase/CouchDB按键的一部分分组并按另一部分排序,couchdb,mapreduce,couchbase,Couchdb,Mapreduce,Couchbase,我有一个用户间信息的数据库。文档看起来像: "_id": "msg_0bec56c1-cbfb-47a5-8882-4a61fec332cd", "_rev": "1-00000eda4d07c93d0000009100000112", "$flags": 0, "$expiration": 0, "Date": 1340280439303, "OwnerId": 35, "RcptId": 37, "SndrId": 35, "Text": "msg5", "Unread": false, "
"_id": "msg_0bec56c1-cbfb-47a5-8882-4a61fec332cd",
"_rev": "1-00000eda4d07c93d0000009100000112",
"$flags": 0,
"$expiration": 0,
"Date": 1340280439303,
"OwnerId": 35,
"RcptId": 37,
"SndrId": 35,
"Text": "msg5",
"Unread": false,
"id": "0bec56c1-cbfb-47a5-8882-4a61fec332cd",
"type": "msg"
对于每条消息,它存储2个具有不同所有者ID的文档。我需要获取一个指定的人和10个uniqe“笔友”之间的最新消息,按最后消息日期排序
var uniqPairs = [];
function(doc){
if (doc.type == "msg"){
if (doc.OwnerId == doc.SndrId){
if (uniqPairs.indexOf(doc.OwnerId + "_" + doc.RcptId) == -1){
uniqPairs.push(doc.SndrId + "_" + doc.RcptId);
uniqPairs.push(doc.RcptId + "_" + doc.SndrId);
emit([doc.OwnerId, doc.Date], {"owner": doc.OwnerId, "from":doc.SndrId, "to":doc.RcptId});
}
}
if (doc.OwnerId == doc.RcptId){
if (uniqPairs.indexOf(doc.OwnerId + "_" + doc.SndrId) == -1){
//uniqPairs.push(doc.SndrId + "_" + doc.RcptId);
uniqPairs.push(doc.RcptId + "_" + doc.SndrId);
emit([doc.OwnerId, doc.Date], {"owner": doc.OwnerId, "from":doc.SndrId, "to":doc.RcptId});
}
}
}
}
我的查询参数:
降序=true&endkey=[35,35]&startkey=[35,35,“{}”]&limit=10&skip=0
我的地图功能:
函数(doc){如果(doc.type==“msg”){
发出([doc.OwnerId,doc.SndrId,doc.Date,doc.RcptId],doc);
发出([doc.OwnerId,doc.RcptId,doc.Date,doc.SndrId],doc);
}
} 结果,我得到了所需帐户的消息列表。键中的最后一个值(第四个)是我们应该将值分组的值
组级别为4的Groupping不起作用,因为日期不同。这是我的新地图功能,它完全符合我的要求,但前提是我只有一台服务器
var uniqPairs = [];
function(doc){
if (doc.type == "msg"){
if (doc.OwnerId == doc.SndrId){
if (uniqPairs.indexOf(doc.OwnerId + "_" + doc.RcptId) == -1){
uniqPairs.push(doc.SndrId + "_" + doc.RcptId);
uniqPairs.push(doc.RcptId + "_" + doc.SndrId);
emit([doc.OwnerId, doc.Date], {"owner": doc.OwnerId, "from":doc.SndrId, "to":doc.RcptId});
}
}
if (doc.OwnerId == doc.RcptId){
if (uniqPairs.indexOf(doc.OwnerId + "_" + doc.SndrId) == -1){
//uniqPairs.push(doc.SndrId + "_" + doc.RcptId);
uniqPairs.push(doc.RcptId + "_" + doc.SndrId);
emit([doc.OwnerId, doc.Date], {"owner": doc.OwnerId, "from":doc.SndrId, "to":doc.RcptId});
}
}
}
}
因此,对于集群I,我牺牲了“按日期排序”,并为map/reduce获得了这样的函数:
地图:
减少:
var tmp = [];
var t = [];
function findRecent(arr){
var max = 0;
var maxId = 0;
for (var i in arr){
if (arr[i].Date > max){
max = arr[i].Date;
maxId = i;
}
}
return arr[maxId];
}
function(k,v,r){
if (!r){
tmp.push(v);
}
else{
tmp.push(v);
}
if (r){
for (var i1 in tmp[0])
{
t.push(tmp[0][i1]);
}
} else {
return findRecent(v);
}
return findRecent(t);
}
如果有人知道更好的解决方案(即如何按日期排序结果),欢迎回答。我创建了reduce函数,可以生成所需的结果。但我不能对它施加10的限制<代码>函数(键、值、返回值){var usrs={};var res=[];var i=0;keys.forEach(函数(键){if(!usrs[key[0][3]]){usrs[key[0][3]]=true;res.push(值[i]);}i=i+1;};返回值;//返回值;}