I have the following Post entity:
public class Post
{
public string Id {get;set;}
public string Text {get;set;}
public IList<Vote> Votes {get;set;}
public IList<Comment> Comments {get;set;}
}
For list of Posts I need to retrieve Id, Text, Rating (sum of votes), CommentsCount. I tried to create the following MapReduce index:
public class PostsForList: AbstractIndexCreationTask<Post, PostsForList.ReduceResult>
{
public class ReduceResult
{
public string Id { get; set; }
public string Text { get; set; }
public long Rating { get; set; }
public long CommentsCount { get; set; }
}
public PostsForList()
{
Map = posts => from post in posts
from comment in post.Comments
from vote in post.Votes
select
new
{
Id = post.Id,
Text = post.Text,
Rating = vote.Value /* 1 or -1 */
CommentsCount = 1,
};
Reduce = results => from result in results
group result by result.Id
into grouped
select
new
{
Id = grouped.Key,
Text = grouped.Select(x => x.Text).First(),
Rating = grouped.Sum(x => x.Rating)
CommentsCount = grouped.Sum(x => x.Rating),
};
}
}
It looked reasonable for me initially. But looks like my Map with three from clauses won’t work. The only other solution I see is to use MultiMap index with two maps (one for votes and one for comments). But it looks a bit strange to use MultiMap index where both indexes query the same document… Are there any other solutions?
Idsa, there’s no need to define an index here. Both collections,
VotesandCommentsare part of the document, so just use them:Update:
I you really want to precompute the results, take a look here: http://daniellang.net/using-an-index-as-a-materialized-view-in-ravendb/