codecombat/scripts/analytics/mongodb/queries/averageLevelPlaytimes.js

159 lines
5.1 KiB
JavaScript
Raw Normal View History

2016-02-11 18:13:57 -05:00
/* global ISODate */
/* global db */
2015-12-15 19:37:42 -05:00
// Average level playtimes in seconds by campaign, broken up by course and campaign levels
2016-02-11 18:13:57 -05:00
// If level sessions has heroConfig set, assuming it's a campaign player rather than a course player
2015-06-11 17:32:10 -04:00
// Usage:
// mongo <address>:<port>/<database> <script file> -u <username> -p <password>
2016-02-11 18:13:57 -05:00
// TODO: this is super slow! Can we utilize indexes on level.sessions collection better?
2015-06-11 17:32:10 -04:00
// NOTE: faster to use find() instead of aggregate()
2015-12-15 19:37:42 -05:00
// NOTE: faster to ask for one level at a time.
2015-06-11 17:32:10 -04:00
2015-12-15 19:37:42 -05:00
var individualCampaigns = ['dungeon', 'forest', 'desert', 'mountain'];
2015-06-11 17:32:10 -04:00
var scriptStartTime = new Date();
2016-02-11 18:13:57 -05:00
var startDay = '2016-01-01';
var endDay = '2016-02-11';
2015-06-11 17:32:10 -04:00
2015-12-15 19:37:42 -05:00
print("Dates: " + startDay + " to " + endDay);
2015-06-11 17:32:10 -04:00
// Print out playtimes for each campaign
2016-02-11 18:13:57 -05:00
var campaigns = getCampaigns();
2015-12-15 19:37:42 -05:00
2016-02-11 18:13:57 -05:00
print("Campaign data followed by course data:")
2015-06-11 17:32:10 -04:00
for (var i = 0; i < campaigns.length; i++) {
var campaign = campaigns[i];
2016-02-11 18:13:57 -05:00
// if (campaign.slug !== 'intro') {
// print('Skipping', campaign.slug);
// continue;
// }
2015-12-15 19:37:42 -05:00
print(campaign.slug);
print("Sessions\tAverage\tSessions\tAverage\tLevel");
for (var j = 0; j < campaign.levelSlugs.length; j++) {
var levelSlug = campaign.levelSlugs[j];
2016-02-11 18:13:57 -05:00
// 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;
// }
2015-12-15 19:37:42 -05:00
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);
2015-06-11 17:32:10 -04:00
}
else {
2015-12-15 19:37:42 -05:00
print(0, '\t', 0, '\t', 0, '\t', 0, '\t', levelSlug);
2015-06-11 17:32:10 -04:00
}
}
// 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
}
2016-02-11 18:13:57 -05:00
function getCampaigns() {
var campaignIDs = [];
var cursor = db.courses.find();
while (cursor.hasNext()) {
campaignIDs.push(cursor.next().campaignID);
}
// printjson(campaignIDs);
2015-06-11 17:32:10 -04:00
var campaigns = [];
2016-02-11 18:13:57 -05:00
cursor = db.campaigns.find({_id: {$in: campaignIDs}}, {slug: 1, levels: 1});
2015-06-11 17:32:10 -04:00
while (cursor.hasNext()) {
var doc = cursor.next();
if (doc.slug === 'auditions') continue;
2016-02-11 18:13:57 -05:00
var campaign = {_id: doc._id.valueOf(), slug: doc.slug, levelSlugs: []};
2015-06-11 17:32:10 -04:00
for (var levelID in doc.levels) {
2015-12-15 19:37:42 -05:00
campaign.levelSlugs.push(doc.levels[levelID].slug);
2015-06-11 17:32:10 -04:00
}
campaigns.push(campaign);
}
2015-12-15 19:37:42 -05:00
campaigns.sort(function (a, b) {
2016-02-11 18:13:57 -05:00
if (campaignIDs.indexOf(a._id) < campaignIDs.indexOf(b._id)){
2015-12-15 19:37:42 -05:00
return -1;
}
return 1;
});
2015-06-11 17:32:10 -04:00
return campaigns;
}
function getPlaytimes(levelSlugs) {
2015-12-15 19:37:42 -05:00
// printjson(levelSlugs);
2015-06-11 17:32:10 -04:00
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}}
]
2015-12-15 19:37:42 -05:00
}, {heroConfig: 1, levelID: 1, playtime: 1});
2015-06-11 17:32:10 -04:00
var playtimes = {};
while (cursor.hasNext()) {
var myDoc = cursor.next();
var levelID = myDoc.levelID;
2015-12-15 19:37:42 -05:00
if (!playtimes[levelID]) playtimes[levelID] = {campaign: [], course: []};
if (myDoc.heroConfig) {
playtimes[levelID].campaign.push(myDoc.playtime);
}
else {
playtimes[levelID].course.push(myDoc.playtime);
}
2015-06-11 17:32:10 -04:00
}
2015-12-15 19:37:42 -05:00
// printjson(playtimes);
2015-06-11 17:32:10 -04:00
var data = {};
for (levelID in playtimes) {
2015-12-15 19:37:42 -05:00
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
}
};
2015-06-11 17:32:10 -04:00
}
return data;
}