2012-06-22 28 views
0

我有用户之间的消息数据库。文件看起来像:Couchbase/CouchDB按部分键和另一部分排序

"_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个文件不同OWNERID。我需要获得一个指定人员与10个唯一“笔友”最后一条消息日期排序的最新消息

我的查询参数:

降序=真& endkey = [35,35] & startkey = [35,35, “{}”] &限制= 10 &跳过= 0

我的地图功能:

功能(DOC){
(doc.OwnerId,doc.SndrId,doc.Date,doc.RcptId],doc);如果(doc.type ==“msg”){
        emit([doc.OwnerId,doc.RcptId,doc.Date,doc.SndrId],doc);
   }
}

结果我得到所需的帐户信息列表。关键字中的最后一个值(第4个)是我们应该将值分组的值。

由于日期不同,导致群组级别4不能正常工作。

+0

我创建了reduce函数,可以生成我需要的结果。但我不能将** limit = 10 **应用于它。 'function(keys,values,rereduce)var usrs = {}; var res = []; var i = 0; (key){if([usrs [key [0] [3]]){ usrs [key [0] [3]] = true; res。 keys.forEach推(值[I]); } i = i + 1; }); return res; //返回值; }' – m03geek

回答

0

这是我的新地图功能,正是我想要的但只有当我有一台服务器

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}); 
     } 
    } 
    } 
} 

所以对于集群我牺牲了 “按日期排序”,并得到了地图等功能/减少:

地图:

function (doc) { 
    if (doc.type == "msg"){ 
    if (doc.OwnerId == doc.SndrId){ 
     emit([doc.OwnerId, doc.RcptId, doc.Date], {"Date":doc.Date, "OwnerId":doc.OwnerId, "RcptId":doc.RcptId, "SndrId":doc.SndrId, "Text":doc.Text, "Unread":doc.Unread, "id": doc.id, "type":doc.type}); 
    } else { 
     emit([doc.OwnerId, doc.SndrId, doc.Date], {"Date":doc.Date, "OwnerId":doc.OwnerId, "RcptId":doc.RcptId, "SndrId":doc.SndrId, "Text":doc.Text, "Unread":doc.Unread, "id": doc.id, "type":doc.type}); 
    } 
    } 
} 

减少:

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); 
} 

如果有人知道更好的解决方案(即如何按日期排除结果) - 欢迎您回答。