/* global ISODate */ /* global db */ // Average level playtimes in seconds by campaign, broken up by course and campaign levels // If level sessions has heroConfig set, assuming it's a campaign player rather than a course player // Usage: // mongo <address>:<port>/<database> <script file> -u <username> -p <password> // TODO: this is super slow! Can we utilize indexes on level.sessions collection better? // NOTE: faster to use find() instead of aggregate() // NOTE: faster to ask for one level at a time. var individualCampaigns = ['dungeon', 'forest', 'desert', 'mountain']; var scriptStartTime = new Date(); var startDay = '2016-01-01'; var endDay = '2016-02-11'; print("Dates: " + startDay + " to " + endDay); // Print out playtimes for each campaign var campaigns = getCampaigns(); print("Campaign data followed by course data:") for (var i = 0; i < campaigns.length; i++) { var campaign = campaigns[i]; // if (campaign.slug !== 'intro') { // print('Skipping', campaign.slug); // continue; // } print(campaign.slug); print("Sessions\tAverage\tSessions\tAverage\tLevel"); for (var j = 0; j < campaign.levelSlugs.length; j++) { var levelSlug = campaign.levelSlugs[j]; // if (['dungeons-of-kithgard', 'gems-in-the-deep', 'shadow-guard', 'enemy-mine', 'true-names', 'fire-dancing', 'loop-da-loop', 'haunted-kithmaze', 'the-second-kithmaze', 'dread-door', 'cupboards-of-kithgard'].indexOf(levelSlug) >= 0) { // print('Skipping', levelSlug); // continue; // } var levelPlaytimes = getPlaytimes([levelSlug]); if (levelPlaytimes[levelSlug]) { print(levelPlaytimes[levelSlug].campaign.count, '\t', levelPlaytimes[levelSlug].campaign.average, '\t', levelPlaytimes[levelSlug].course.count, '\t', levelPlaytimes[levelSlug].course.average, '\t', levelSlug); } else { print(0, '\t', 0, '\t', 0, '\t', 0, '\t', levelSlug); } } // break; } log("Script runtime: " + (new Date() - scriptStartTime)); function log(str) { print(new Date().toISOString() + " " + str); } function objectIdWithTimestamp(timestamp) { // Convert string date to Date object (otherwise assume timestamp is a date) if (typeof(timestamp) == 'string') timestamp = new Date(timestamp); // Convert date object to hex seconds since Unix epoch var hexSeconds = Math.floor(timestamp/1000).toString(16); // Create an ObjectId with that hex timestamp var constructedObjectId = ObjectId(hexSeconds + "0000000000000000"); return constructedObjectId } function getCampaigns() { var campaignIDs = []; var cursor = db.courses.find(); while (cursor.hasNext()) { campaignIDs.push(cursor.next().campaignID); } // printjson(campaignIDs); var campaigns = []; cursor = db.campaigns.find({_id: {$in: campaignIDs}}, {slug: 1, levels: 1}); while (cursor.hasNext()) { var doc = cursor.next(); if (doc.slug === 'auditions') continue; var campaign = {_id: doc._id.valueOf(), slug: doc.slug, levelSlugs: []}; for (var levelID in doc.levels) { campaign.levelSlugs.push(doc.levels[levelID].slug); } campaigns.push(campaign); } campaigns.sort(function (a, b) { if (campaignIDs.indexOf(a._id) < campaignIDs.indexOf(b._id)){ return -1; } return 1; }); return campaigns; } function getPlaytimes(levelSlugs) { // printjson(levelSlugs); var startObj = objectIdWithTimestamp(ISODate(startDay + "T00:00:00.000Z")); var endObj = objectIdWithTimestamp(ISODate(endDay + "T00:00:00.000Z")) var cursor = db['level.sessions'].find({ $and: [ {"state.complete": true}, {"playtime": {$gt: 0}}, {levelID: {$in: levelSlugs}}, {_id: {$gte: startObj}}, {_id: {$lt: endObj}} ] }, {heroConfig: 1, levelID: 1, playtime: 1}); var playtimes = {}; while (cursor.hasNext()) { var myDoc = cursor.next(); var levelID = myDoc.levelID; if (!playtimes[levelID]) playtimes[levelID] = {campaign: [], course: []}; if (myDoc.heroConfig) { playtimes[levelID].campaign.push(myDoc.playtime); } else { playtimes[levelID].course.push(myDoc.playtime); } } // printjson(playtimes); var data = {}; for (levelID in playtimes) { var campaignTotal = 0; var courseTotal = 0; if (playtimes[levelID].campaign.length > 0) { campaignTotal = playtimes[levelID].campaign.reduce(function(a, b) {return a + b;}); } if (playtimes[levelID].course.length > 0) { courseTotal = playtimes[levelID].course.reduce(function(a, b) {return a + b;}); } var campaignAverage = parseInt(playtimes[levelID].campaign.length > 0 ? parseInt(campaignTotal / playtimes[levelID].campaign.length): 0); var courseAverage = parseInt(playtimes[levelID].course.length > 0 ? parseInt(courseTotal / playtimes[levelID].course.length): 0); data[levelID] = { campaign: { count: playtimes[levelID].campaign.length, total: campaignTotal, average: campaignAverage }, course: { count: playtimes[levelID].course.length, total: courseTotal, average: courseAverage } }; } return data; }