Skip to content

Instantly share code, notes, and snippets.

@phinett
Created April 19, 2012 11:47
Show Gist options
  • Save phinett/2420435 to your computer and use it in GitHub Desktop.
Save phinett/2420435 to your computer and use it in GitHub Desktop.
AudioUpdateConsoleTask.cs
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