Created
April 19, 2012 11:47
-
-
Save phinett/2420435 to your computer and use it in GitHub Desktop.
AudioUpdateConsoleTask.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace HM.AudioStatisticsUpdateTask | |
{ | |
public static class StatsTask | |
{ | |
public static void Execute() | |
{ | |
IList<string> dayYears = new List<string>(); | |
// this is so we can query on our index for the last 7 days | |
for (int i = 0; i < 7; i++) | |
dayYears.Add(DateTimeOffset.Now.DayOfYear - i + "-" + DateTimeOffset.Now.AddDays((i*-1)).Year); | |
// perform this for each tenant in our database | |
foreach (var tenant in Program.Tenants) | |
{ | |
bool weHaveResults = true; | |
int page = 0; | |
int counter = 0; | |
Console.WriteLine("Beginning Tenant: " + tenant.Name); | |
// loop through weekly totals until we have no more results to process | |
while (weHaveResults) | |
{ | |
using (var session = Program.DocumentStore.OpenSession(tenant.TenantKey)) | |
{ | |
// we need to process all of our audio documents in a while loop | |
RavenQueryStatistics stats; | |
var audios = session.Query<Audio, Audio_Index>() | |
.Statistics(out stats) | |
//.Where(x => x.WeeksDownloads > 0 || x.WeeksLikes > 0 || x.WeeksPlays > 0 || x.WeeksFavourites > 0 || x.WeeksComments > 0) // cant do this otherwise it wont include mixes that haven't had any plays for a while, but have been played this week | |
.OrderBy(x => x.DateAdded) | |
.Skip(page * 128) | |
.Take(128) | |
.ToList(); | |
var audioIds = audios.Select(x => x.Id).ToArray(); | |
// get all audio stats from the last 7 days, they will be grouped by day number of the year so we need to group them by audioId in memory after | |
var weeksStats = | |
session.Query<AudioWeeklyStatsCounter_Index.ReduceResult, AudioWeeklyStatsCounter_Index>() | |
.Where(x => x.DayYear.In(dayYears) && x.AudioId.In(audioIds)) | |
.Take(1024) | |
.ToList(); | |
// we need to group them by audioId in memory so we have a total count for the last 7 days per audioId | |
var grouped = (from stat in weeksStats | |
group stat by stat.AudioId | |
into g | |
select new AudioWeeklyStatsCounter_Index.ReduceResult() | |
{ | |
AudioId = g.Key, | |
WeeksComments = g.Sum(x => x.WeeksComments), | |
WeeksDownloads = g.Sum(x => x.WeeksDownloads), | |
WeeksFavourites = g.Sum(x => x.WeeksFavourites), | |
WeeksLikes = g.Sum(x => x.WeeksLikes), | |
WeeksPlays = g.Sum(x => x.WeeksPlays) | |
}).ToDictionary(x => x.AudioId, x => x); | |
// update each audio from this collection with the new weekly statistics | |
foreach (var audio in audios) | |
{ | |
// get our weekly stats for this audio document, or if none found (means we have no plays / downloads etc in the last 7 days) then | |
// create a blank ReduceResult which will have 0 for the stats | |
var weekStat = grouped.ContainsKey(audio.Id) ? grouped[audio.Id] : | |
new AudioWeeklyStatsCounter_Index.ReduceResult() {AudioId = audio.Id}; | |
// check to make sure the values are different, we dont want to perform redundent SaveChanges if we don't have to | |
// RavenDb may already do this for us, but just a sanity check i suppose as this process can be pretty expensive. | |
//if (audio.WeeksPlays != weekStat.WeeksPlays) | |
// audio.WeeksPlays = weekStat.WeeksPlays; | |
//if (audio.WeeksDownloads != weekStat.WeeksDownloads) | |
// audio.WeeksDownloads = weekStat.WeeksDownloads; | |
//if (audio.WeeksLikes != weekStat.WeeksLikes) | |
// audio.WeeksLikes = weekStat.WeeksLikes; | |
//if (audio.WeeksFavourites != weekStat.WeeksFavourites) | |
// audio.WeeksFavourites = weekStat.WeeksFavourites; | |
//if (audio.WeeksComments != weekStat.WeeksComments) | |
// audio.WeeksComments = weekStat.WeeksComments; | |
bool isDirty = false; | |
if (audio.WeeksPlays != weekStat.WeeksPlays) | |
isDirty = true; | |
if (audio.WeeksDownloads != weekStat.WeeksDownloads) | |
isDirty = true; | |
if (audio.WeeksLikes != weekStat.WeeksLikes) | |
isDirty = true; | |
if (audio.WeeksFavourites != weekStat.WeeksFavourites) | |
isDirty = true; | |
if (audio.WeeksComments != weekStat.WeeksComments) | |
isDirty = true; | |
if (isDirty) | |
{ | |
Program.DocumentStore.DatabaseCommands.ForDatabase(tenant.TenantKey) | |
.Patch(audio.Id, new PatchRequest[] | |
{ | |
new PatchRequest() | |
{ | |
Type = PatchCommandType.Set, | |
Name = "WeeksPlays", | |
Value = weekStat.WeeksPlays | |
}, | |
new PatchRequest() | |
{ | |
Type = PatchCommandType.Set, | |
Name = "WeeksDownloads", | |
Value = weekStat.WeeksDownloads | |
}, | |
new PatchRequest() | |
{ | |
Type = PatchCommandType.Set, | |
Name = "WeeksComments", | |
Value = weekStat.WeeksComments | |
}, | |
new PatchRequest() | |
{ | |
Type = PatchCommandType.Set, | |
Name = "WeeksFavourites", | |
Value = weekStat.WeeksFavourites | |
}, | |
new PatchRequest() | |
{ | |
Type = PatchCommandType.Set, | |
Name = "WeeksLikes", | |
Value = weekStat.WeeksLikes | |
} | |
}); | |
} | |
counter++; | |
Console.WriteLine("Updated " + weekStat.AudioId + " " + counter + "/" + stats.TotalResults); | |
} | |
//session.SaveChanges(); | |
// if we don't have any results to process, end the while loop | |
if (!audios.Any()) | |
weHaveResults = false; | |
page++; | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment