Kent V
Kent V

Reputation: 563

User rating based on response time in MongoDB

For example. Users A posts a product for sell. Users B click to see product and would like to chat with user A. The response time is the time from when user B click on chat button with user A until user A replies.

What I need to do is there're many users like user B and I need to display average response time of users. E.g: user A respond to user B in 2 mins, to user C in 4 mins, so the average response time is 3mins.

Here's my moongoose schemas:

var users = new Schema({
    _id: ObjectId,
    name:  String,
    averageResponseTime: Number,
});

var userResponseTime = new Schema({
    _id: ObjectId,
    userId:  ObjectId,
    respondToUserId: ObjectId,
    responseTime: Number
});

I need to be able to get and display average response time in user profile page.

What's recommended way to calculate and store averageResponseTime value?

I'm thinking to have cron job to runs every 5 minutes to calculate avarage time based on data from userResponseTime but I don't like this since it consumes resources

Anyone has experience with this please help.

Thanks!

Upvotes: 1

Views: 377

Answers (1)

ByteMaster
ByteMaster

Reputation: 182

To display/calculate value you need to get related userResponseTime objects for selected user. So here the plan

  1. Get all collection data for userResponseTime
  2. Calculate average response time for current selected user

      userResponseTimeCollection.find({"userId":{$eq:require('mongoose').Types.ObjectId(userId)}}).toArray(function(err, results) {
        var responseTimes = 0;
        var responseCount = 0;
        var avgResponseTime = 0;
    
        results.forEach(function(item, i, arr){
          responseTimes += item.responseTime;
          responseCount++;
        });
        if(responseCount > 0)
          avgResponseTime = responseTimes / responseCount;
      });
    

Or you can get all data for users, all for their responses, and after that got through loop

  var users = [];
  var userResponses = [];

  usersCollection.find({}).toArray(function(err, results) {
    if(results)
      users = results;
  });

  userResponseTimeCollection.find({}).toArray(function(err, results) {
    if(results)
      userResponses = results;
  });

  users.forEach(function(user) {
    var responseTimes = 0;
    var responseCount = 0;
    var avgResponseTime = 0;    
    userResponses.forEach(function(response) {
      if(response.userId == user._id){
        responseTimes += response.responseTime;
        responseCount++;
      }
    });
    if(responseCount > 0)
      avgResponseTime = responseTimes / responseCount;
    user.ResponseRate = avgResponseTime;
  });

Maybe it looks overwhelming but hope you got the main idea. GL!

BTW. If you need to keep such data about avg response it's way better to recalculate avg time on pre/post hook for mongoose http://mongoosejs.com/docs/subdocs.html

Upvotes: 1

Related Questions