0

我有一个用户之间的消息数据库。文档看起来像:

"_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 “笔友”之间的最新消息。

我的查询参数:

降序=true&endkey=[35,35]&startkey=[35,35,"{}"]&limit=10&skip=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);
   }
}

结果,我得到了所需帐户的消息列表。键中的最后一个值(第 4 个)是我们应该对值进行分组的值。

由于日期不同,组级别 4 的分组不起作用。

4

1 回答 1

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

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

于 2012-06-23T09:49:18.487 回答