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;};返回值;//返回值;}