From 9624885fe26b742a2efc54a1efe0883cb0c91e35 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Sat, 14 Nov 2015 16:34:35 -0800 Subject: [PATCH] Aggregating UserCodeProblems by level with an index instead of aggregating all ever --- .../user_code_problems/UserCodeProblem.coffee | 2 ++ .../user_code_problem_handler.coffee | 35 +++---------------- 2 files changed, 6 insertions(+), 31 deletions(-) diff --git a/server/user_code_problems/UserCodeProblem.coffee b/server/user_code_problems/UserCodeProblem.coffee index e901a7705..148813635 100644 --- a/server/user_code_problems/UserCodeProblem.coffee +++ b/server/user_code_problems/UserCodeProblem.coffee @@ -8,4 +8,6 @@ UserCodeProblemSchema = new mongoose.Schema({ 'default': Date.now }, {strict: false,read:config.mongo.readpref}) +UserCodeProblemSchema.index {levelID: 1, _id: 1}, {name: 'user code problems by level and date index'} + module.exports = UserCodeProblem = mongoose.model('user.code.problem', UserCodeProblemSchema) diff --git a/server/user_code_problems/user_code_problem_handler.coffee b/server/user_code_problems/user_code_problem_handler.coffee index 968e2d2c2..9f3aa780b 100644 --- a/server/user_code_problems/user_code_problem_handler.coffee +++ b/server/user_code_problems/user_code_problem_handler.coffee @@ -47,45 +47,18 @@ class UserCodeProblemHandler extends Handler return @sendSuccess res, [] unless levelSlug? - # Cache results for 1 day - @commonLevelProblemsCache ?= {} - @commonLevelProblemsCachedSince ?= new Date() - if (new Date()) - @commonLevelProblemsCachedSince > 86400 * 1000 # Dumb cache expiration - @commonLevelProblemsCache = {} - @commonLevelProblemsCachedSince = new Date() - cacheKey = levelSlug - cacheKey += 's' + startDay if startDay? - cacheKey += 'e' + endDay if endDay? - return @sendSuccess res, commonProblems if commonProblems = @commonLevelProblemsCache[cacheKey] - # Build query - match = if startDay? or endDay? then {$match: {$and: []}} else {$match: {}} + match = if startDay? or endDay? then {$match: {$and: [levelID: levelSlug]}} else {$match: {levelID: levelSlug}} match["$match"]["$and"].push _id: {$gte: utils.objectIdFromTimestamp(startDay + "T00:00:00.000Z")} if startDay? match["$match"]["$and"].push _id: {$lt: utils.objectIdFromTimestamp(endDay + "T00:00:00.000Z")} if endDay? group = {"$group": {"_id": {"errMessage": "$errMessageNoLineInfo", "errHint": "$errHint", "language": "$language", "levelID": "$levelID"}, "count": {"$sum": 1}}} sort = { $sort : { "_id.levelID": 1, count : -1, "_id.language": 1 } } query = UserCodeProblem.aggregate match, group, sort + query.cache() query.exec (err, data) => if err? then return @sendDatabaseError res, err - - # Build per-level common problem lists - commonProblems = {} - for item in data - levelID = item._id.levelID - commonProblems[levelID] ?= [] - commonProblems[levelID].push - language: item._id.language - message: item._id.errMessage - hint: item._id.errHint - count: item.count - - # Cache all the levels - for levelID of commonProblems - cacheKey = levelID - cacheKey += 's' + startDay if startDay? - cacheKey += 'e' + endDay if endDay? - @commonLevelProblemsCache[cacheKey] = commonProblems[levelID] - @sendSuccess res, commonProblems[levelSlug] + formatted = ({language: item._id.language, message: item._id.errMessage, hint: item._id.errHint, count: item.count} for item in data) + @sendSuccess res, formatted module.exports = new UserCodeProblemHandler()