Couchbase custom reduce function

2019-07-25 07:50发布

I have some documents in my Couchbase with the following template:

{
  "id": 102750,
  "status": 5,
  "updatedAt": "2014-09-10T10:50:39.297Z",
  "points1": 1,
  "points2": -3,
  "user1": {
      "id": 26522,
      ...
  },
  "user2": {
      "id": 38383,
      ...
  },
  ....
}

What I want to do is to group the documents on the user and sum the points for each user and then show the top 100 users in the last week. I have been circling around but I haven't come with any solution.

I have started with the following map function:

function (doc, meta) {
  if (doc.user1 && doc.user2) {
    emit(doc.user1.id, doc.points1);
    emit(doc.user2.id, doc.points2);
  }
}

and then tried the sum to reduce the results but clearly I was wrong because I wasn't able to sort on the points and I couldn't also include the date parameter

2条回答
相关推荐>>
2楼-- · 2019-07-25 08:04

I have solved this issue by the help of a server side script. What I have done is I changed my map function to be like this:

function (doc, meta) {
  if (doc.user1 && doc.user2) {
    emit(dateToArray(doc.createdAt), { 'userId': doc.user1.id, 'points': doc.points1});
    emit(dateToArray(doc.createdAt), { 'userId': doc.user2.id, 'points': doc.points2});
  }
}

And in the script I query the view with the desired parameters and then I group and sort them then send the top 100 users.

I am using Node JS so my script is like this: (the results are what I read from couchbase view)

function filterResults(results) {
  debug('filtering ' + results.length + ' entries..');
  // get the values
  var values = _.pluck(results, 'value');
  var groupedUsers = {};

  // grouping users and sum their points in the games
  // groupedUsers will be like the follwoing:
  //  { 
  //     '443322': 33,
  //     '667788': 55,
  //     ...
  //   }
  for (var val in values) {
    var userId = values[val].userId;
    var points = values[val].points;
    if (_.has(groupedUsers, userId)) {
      groupedUsers[userId] += points;
    }
    else
      groupedUsers[userId] = points;
  }

  // changing the groupedUsers to array form so it can be sorted by points:
  // [['443322', 33], ['667788', 55], ...]
  var topUsers = _.pairs(groupedUsers);

  // sort descending
  topUsers.sort(function(a, b) {
    return b[1] - a[1];
  });

  debug('Number of users: ' + topUsers.length + '. Returning top 100 users');
  return _.first(topUsers, 100);
}
查看更多
不美不萌又怎样
3楼-- · 2019-07-25 08:08

you need to see my exemple I was able to group by date and show the values with reduce. but calculate the sum I did it in my program.

see the response How can I groupBy and change content of the value in couchbase?

查看更多
登录 后发表回答