Created
November 18, 2011 11:50
-
-
Save mattwarren/1376252 to your computer and use it in GitHub Desktop.
Funky Map reduce
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
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Linq; | |
using System.Threading; | |
using Raven.Abstractions.Extensions; | |
using Raven.Client.Embedded; | |
using Raven.Client.Indexes; | |
using Raven.Client.Linq; | |
using Raven.Database.Impl; | |
using Raven.Json.Linq; | |
using Raven.Tests.Bugs; | |
using Raven.Tests.Faceted; | |
using Raven.Tests.Patching; | |
using Raven.Tests; | |
using Xunit; | |
using Raven.Client; | |
using Raven.Abstractions.Indexing; | |
using System.ComponentModel.Composition.Hosting; | |
namespace Raven.Tryouts | |
{ | |
class Program | |
{ | |
static void Main() | |
{ | |
new RollingAverageTest().CanDoARollingAverage_Embedded(); | |
} | |
} | |
public class RollingAverageTest : RavenTest | |
{ | |
[Fact] | |
public void CanDoARollingAverage_Embedded() | |
{ | |
using (var store = NewDocumentStore()) | |
{ | |
ExecuteTest(store); | |
} | |
} | |
private void ExecuteTest(IDocumentStore store) | |
{ | |
IndexCreation.CreateIndexes(new CompositionContainer(new TypeCatalog(typeof(RollingAverageIndex))), store); | |
SeedDate(store); | |
if (store is EmbeddableDocumentStore) | |
WaitForUserToContinueTheTest(store as EmbeddableDocumentStore); | |
using (var s = store.OpenSession()) | |
{ | |
s.Store(new Match | |
{ | |
Date = new DateTime(2011, 5, 30), | |
Games = new List<Game> | |
{ | |
new Game { Player = "matt", Pins = 1 }, | |
new Game { Player = "archie", Pins = 300 }, | |
} | |
}); | |
s.SaveChanges(); | |
} | |
if (store is EmbeddableDocumentStore) | |
WaitForUserToContinueTheTest(store as EmbeddableDocumentStore); | |
} | |
private void SeedDate(IDocumentStore store) | |
{ | |
using (var s = store.OpenSession()) | |
{ | |
s.Store(new Match | |
{ | |
Date = new DateTime(2011, 5, 21), | |
Games = new List<Game> | |
{ | |
new Game { Player = "bob", Pins = 250 }, | |
new Game { Player = "matt", Pins = 120 }, | |
new Game { Player = "james", Pins = 180 }, | |
new Game { Player = "archie", Pins = 100 }, | |
} | |
}); | |
s.Store(new Match | |
{ | |
Date = new DateTime(2011, 5, 22), | |
Games = new List<Game> | |
{ | |
new Game { Player = "bob", Pins = 200 }, | |
new Game { Player = "matt", Pins = 130 }, | |
new Game { Player = "james", Pins = 170 }, | |
new Game { Player = "archie", Pins = 100 }, | |
} | |
}); | |
s.Store(new Match | |
{ | |
Date = new DateTime(2011, 5, 23), | |
Games = new List<Game> | |
{ | |
new Game { Player = "bob", Pins = 250 }, | |
new Game { Player = "matt", Pins = 140 }, | |
new Game { Player = "james", Pins = 160 }, | |
new Game { Player = "archie", Pins = 50 }, | |
} | |
}); | |
s.SaveChanges(); | |
} | |
} | |
} | |
public class RollingAverageIndex : AbstractIndexCreationTask | |
{ | |
public override IndexDefinition CreateIndexDefinition() | |
{ | |
return new IndexDefinitionBuilder<Match, AvgResult> | |
{ | |
Map = matches => from match in matches | |
where match.Games != null | |
from game in match.Games | |
select new | |
{ | |
MinDate = match.Date, | |
Player = game.Player, | |
AveragePins = game.Pins, | |
Last2Games = Enumerable.Repeat(new { match.Date, game.Pins, game.Player }, 1), | |
Last2GamesAvg = game.Pins, | |
TotalGames = 1 | |
}, | |
Reduce = results => from result in results | |
group result by result.Player | |
into g | |
//let last2Games = g.SelectMany(x => x.Last2Games).OrderByDescending(x => x.Date).Take(2) | |
select new | |
{ | |
MinDate = new DateTime(g.Min(x => x.MinDate.Ticks)), | |
Last2Games = g.SelectMany(x => x.Last2Games).OrderByDescending(x => x.Date).Take(2), | |
Player = g.Key, | |
AveragePins = g.Average(x => x.AveragePins), | |
Last2GamesAvg = g.SelectMany(x => x.Last2Games).OrderByDescending(x => x.Date).Take(2).Average(x => x.Pins), //how to do this?? | |
TotalGames = g.Sum(x => x.TotalGames) | |
} | |
}.ToIndexDefinition(Conventions); | |
} | |
} | |
public class Match | |
{ | |
public string Id { get; set; } | |
public DateTime Date { get; set; } | |
public List<Game> Games { get; set; } | |
} | |
public class Game | |
{ | |
public DateTime Date { get; set; } | |
public string Player { get; set; } | |
public long Pins { get; set; } | |
} | |
public class AvgResult | |
{ | |
public DateTime MinDate { get; set; } | |
public string Player { get; set; } | |
public double AveragePins { get; set; } | |
public double Last2GamesAvg { get; set; } | |
public IEnumerable<Game> Last2Games { get; set; } | |
public int TotalGames { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi Matt!
This code was written as a response to https://groups.google.com/forum/#!msg/ravendb/X-xEw9Ea77Q/0wpqpAQRiIYJ. I've been using an index like this successfully for a year, but with the latest RavenDB unstable version I am seeing strange results. Do you know if this method (OrderByDescending I presume) is still supported in RavenDB 1.2?