Created
November 7, 2012 12:40
-
-
Save etishor/4031390 to your computer and use it in GitHub Desktop.
Multi map reduce index
This file contains hidden or 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.Linq; | |
using Raven.Client; | |
using Raven.Client.Document; | |
using Raven.Client.Indexes; | |
namespace RavenTest | |
{ | |
public class ExtractionUser | |
{ | |
public string Id { get; set; } | |
public string[] AssignedFields { get; set; } | |
} | |
public class WorkItem | |
{ | |
public string Id { get; set; } | |
public string DocumentId { get; set; } | |
public string FieldId { get; set; } | |
public string Status { get; set; } | |
} | |
public class UserWorkItem : AbstractMultiMapIndexCreationTask<UserWorkItem.Result> | |
{ | |
public class Result | |
{ | |
public string FieldId { get; set; } | |
public string UserId { get; set; } | |
public string DocumentId { get; set; } | |
public int Count { get; set; } | |
public int Validated { get; set; } | |
} | |
public UserWorkItem() | |
{ | |
AddMap<ExtractionUser>(users => users.SelectMany(u => u.AssignedFields, (user, fied) => new | |
{ | |
FieldId = fied, | |
UserId = user.Id, | |
DocumentId = (string)null, | |
Count = 0, | |
Validated = 0 | |
})); | |
AddMap<WorkItem>(items => items.Select(item => new | |
{ | |
FieldId = item.FieldId, | |
UserId = (string)null, | |
DocumentId = item.DocumentId, | |
Count = 1, | |
Validated = item.Status == "Validated" ? 1 : 0 | |
})); | |
Reduce = results => results.GroupBy(r => r.FieldId) | |
// gather all the users and all the documents with a common field | |
.Select(g => new | |
{ | |
FieldId = g.Key, | |
Users = g.Where(u => u.UserId != null) | |
.Select(d => d.UserId) | |
.DefaultIfEmpty(), | |
Documents = g.Where(d => d.DocumentId != null) | |
.Select(d => new | |
{ | |
DocumentId = d.DocumentId, | |
Count = d.Count, | |
Validated = d.Validated | |
}).DefaultIfEmpty(new | |
{ | |
DocumentId = (string)null, | |
Count = 0, | |
Validated = 0 | |
}) | |
}) | |
// make all combinations of field , user , document by .SelectMany first on Users then on Documents | |
.SelectMany(d => d.Users, (d, user) => new | |
{ | |
FieldId = d.FieldId, | |
UserId = user, | |
Documents = d.Documents, | |
}) | |
.SelectMany(d => d.Documents, (d, document) => new | |
{ | |
// if we have a value for UserId and for DocumentId then compose a FieldId from these values else use the initial FieldId | |
FieldId = (d.UserId != null && document.DocumentId != null) ? | |
d.UserId + " " + document.DocumentId : d.FieldId, | |
UserId = d.UserId, | |
DocumentId = document.DocumentId, | |
Count = document.Count, | |
Validated = document.Validated | |
}) | |
// aggregate the final result | |
.GroupBy(d => new { d.FieldId, d.UserId, d.DocumentId }) | |
.Select(g => new | |
{ | |
FieldId = g.Key.FieldId, | |
UserId = g.Key.UserId, | |
DocumentId = g.Key.DocumentId, | |
Count = g.Sum(d => d.Count), | |
Validated = g.Sum(d => d.Validated) | |
}); | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
//using (EmbeddableDocumentStore store = new EmbeddableDocumentStore { RunInMemory = true }) | |
using (DocumentStore store = new DocumentStore { ConnectionStringName = "RavenDb" }) | |
{ | |
store.Initialize(); | |
IndexCreation.CreateIndexes(typeof(UserWorkItem).Assembly, store); | |
//using (var session = store.OpenSession()) | |
//{ | |
// CreateDocs(session); | |
// session.SaveChanges(); | |
//} | |
//using (var session = store.OpenSession()) | |
//{ | |
// var result = session.Query<WorkItem, UserWorkItem>() | |
// .Customize(q => q.WaitForNonStaleResults()) | |
// .As<UserWorkItem.Result>() | |
// .ToArray(); | |
//} | |
} | |
Console.WriteLine("Done"); | |
Console.ReadKey(); | |
} | |
private static void CreateDocs(IDocumentSession session) | |
{ | |
//ExtractionUser u1 = new ExtractionUser { Id = "ExtractionUsers/1", AssignedFields = new string[] { "field1", "field2" } }; | |
//ExtractionUser u2 = new ExtractionUser { Id = "ExtractionUsers/2", AssignedFields = new string[] { "field1", "field3" } }; | |
//ExtractionUser u3 = new ExtractionUser { Id = "ExtractionUsers/3", AssignedFields = new string[] { "field1", "field4" } }; | |
//WorkItem wi1 = new WorkItem { DocumentId = "documents/1", FieldId = "field1", Status = "Ready" }; | |
//WorkItem wi2 = new WorkItem { DocumentId = "documents/1", FieldId = "field2", Status = "Ready" }; | |
//WorkItem wi3 = new WorkItem { DocumentId = "documents/1", FieldId = "field3", Status = "Ready" }; | |
//WorkItem wi4 = new WorkItem { DocumentId = "documents/1", FieldId = "field4", Status = "Ready" }; | |
//WorkItem wi5 = new WorkItem { DocumentId = "documents/2", FieldId = "field1", Status = "Ready" }; | |
//WorkItem wi6 = new WorkItem { DocumentId = "documents/2", FieldId = "field2", Status = "Ready" }; | |
//WorkItem wi7 = new WorkItem { DocumentId = "documents/2", FieldId = "field3", Status = "Ready" }; | |
//WorkItem wi8 = new WorkItem { DocumentId = "documents/2", FieldId = "field4", Status = "Ready" }; | |
//WorkItem wi9 = new WorkItem { DocumentId = "documents/3", FieldId = "field4", Status = "Ready" }; | |
//session.Store(wi9); | |
//session.Store(u1); | |
//session.Store(u2); | |
//session.Store(u3); | |
//session.Store(wi1); | |
//session.Store(wi2); | |
//session.Store(wi3); | |
//session.Store(wi4); | |
//session.Store(wi5); | |
//session.Store(wi6); | |
//session.Store(wi7); | |
//session.Store(wi8); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment