mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-27 17:45:40 -05:00
Aggregating UserCodeProblems by level with an index instead of aggregating all ever
This commit is contained in:
parent
3562b50bc0
commit
9624885fe2
2 changed files with 6 additions and 31 deletions
|
@ -8,4 +8,6 @@ UserCodeProblemSchema = new mongoose.Schema({
|
||||||
'default': Date.now
|
'default': Date.now
|
||||||
}, {strict: false,read:config.mongo.readpref})
|
}, {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)
|
module.exports = UserCodeProblem = mongoose.model('user.code.problem', UserCodeProblemSchema)
|
||||||
|
|
|
@ -47,45 +47,18 @@ class UserCodeProblemHandler extends Handler
|
||||||
|
|
||||||
return @sendSuccess res, [] unless levelSlug?
|
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
|
# 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: {$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?
|
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}}}
|
group = {"$group": {"_id": {"errMessage": "$errMessageNoLineInfo", "errHint": "$errHint", "language": "$language", "levelID": "$levelID"}, "count": {"$sum": 1}}}
|
||||||
sort = { $sort : { "_id.levelID": 1, count : -1, "_id.language": 1 } }
|
sort = { $sort : { "_id.levelID": 1, count : -1, "_id.language": 1 } }
|
||||||
query = UserCodeProblem.aggregate match, group, sort
|
query = UserCodeProblem.aggregate match, group, sort
|
||||||
|
query.cache()
|
||||||
|
|
||||||
query.exec (err, data) =>
|
query.exec (err, data) =>
|
||||||
if err? then return @sendDatabaseError res, err
|
if err? then return @sendDatabaseError res, err
|
||||||
|
formatted = ({language: item._id.language, message: item._id.errMessage, hint: item._id.errHint, count: item.count} for item in data)
|
||||||
# Build per-level common problem lists
|
@sendSuccess res, formatted
|
||||||
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]
|
|
||||||
|
|
||||||
module.exports = new UserCodeProblemHandler()
|
module.exports = new UserCodeProblemHandler()
|
||||||
|
|
Loading…
Reference in a new issue