Skip to content

Instantly share code, notes, and snippets.

@mattwarren
Created November 18, 2011 11:50
Show Gist options
  • Save mattwarren/1376252 to your computer and use it in GitHub Desktop.
Save mattwarren/1376252 to your computer and use it in GitHub Desktop.
Funky Map reduce
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; }
}
}
@dlidstrom
Copy link

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment