我有以下Post实体:
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;}
}
对于帖子列表,我需要检索Id,文本,评级(票数总和),CommentsCount。我尝试创建以下MapReduce索引:
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),
};
}
}
我最初看起来很合理。但看起来我的地图有三个from子句将无法正常工作。我看到的唯一其他解决方案是使用带有两个映射的MultiMap索引(一个用于投票,一个用于注释)。但是使用MultiMap索引看起来有点奇怪,其中两个索引都查询同一个文档......还有其他解决方案吗?
答案 0 :(得分:3)
Idsa,这里没有必要定义索引。这两个集合Votes
和Comments
都是文档的一部分,因此只需使用它们:
var posts = documentSession.Query<Post>()
.Skip(CurrentPage*PageSize)
.Take(PageSize)
.ToList(); // here is the db-call! all following is just in-memory
var viewModelPosts = from post in posts
select new
{
post.Id,
post.Text,
Rating = post.Votes.Sum(x => x.Value),
CommentsCount = post.Comments.Count
};
<强>更新强>: 我确实想要预先计算结果,请看一下:http://daniellang.net/using-an-index-as-a-materialized-view-in-ravendb/