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"

メッセージごとに、OwnerIdが異なる2つのドキュメントが保存されます。指定された1人の人と最後のメッセージの日付順に並べられた10人のユニークな「ペンフレンド」との間の最新のメッセージを取得する必要があります。

私のクエリパラメータ:

下降=true&endkey = [35,35]&startkey = [35,35、 "{}"]&limit = 10&skip = 0

私のマップ機能:

function(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

これは、私が望んでいたことを正確に実行する新しいマップ関数ですが、サーバーが1つの場合にのみです

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

誰かがより良い解決策 (つまり、結果を日付で並べ替える方法) を知っている場合は、喜んで回答してください。

于 2012-06-23T09:49:18.487 に答える