Couchbase / CouchDB按键的一部分进行分组,另一部分按顺序排序

时间:2012-06-22 11:54:08

标签: 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": "0bec56c1-cbfb-47a5-8882-4a61fec332cd",
"type": "msg"

对于每条消息,它存储2个具有不同OwnerId的文档。我需要在一个指定的人和 10 uniqe “笔友”按照上次消息日期排序之间获得最新消息。

我的查询参数:

  

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

我的地图功能:

  

功能(doc){
   if(doc.type ==“msg”){
   emit([doc.OwnerId,doc.SndrId,doc.Date,doc.RcptId],doc);
   发出([doc.OwnerId,doc.RcptId,doc.Date,doc.SndrId],doc);
   }
   }

结果我得到了所需帐户的邮件列表。 key中的最后一个值(4th)是我们应该对值进行分组的值。

由于日期不同,因此第4组无法进行分组。

1 个答案:

答案 0 :(得分: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});
      }
    }
  }
}

因此,对于集群,我牺牲了“按日期排序”并获得了map / reduce的功能:

地图:

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

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