1

我希望能够从 RavenDB 中的集合中查询前 10 个文档,该集合按计数排序,并带有子列表中的约束。这是我的实体:

public class Post
{
    public string Title { get; set; }
    public List<Like> Likes { get; set; }
}

public class Like
{
    public DateTime Created { get; set; }
}

我尝试过以下查询:

var oneMonthAgo = DateTime.Today.AddMonths(-1);
session
    .Query<Post>()
    .OrderByDescending(x => x.Likes.Count(y => y.Created > oneMonthAgo))
    .Take(10);

Raven 抱怨应该在索引时间而不是查询时间上完成计数。我尝试使用以下代码将计数移动到索引:

public class PostsIndex : AbstractIndexCreationTask<Post>
{
    public PostsIndex()
    {
        var month = DateTime.Today.AddMonths(-1);
        Map = posts => from doc in posts
                       select
                           new
                               {
                                   doc.Title,
                                   LikeCount = doc.Likes.Count(x => x.Created > month),
                               };
    }
}

添加此索引时,Raven 会抛出错误 500。

该怎么办?

4

1 回答 1

1

您可以通过创建一个 Map/Reduce 索引来展平帖子/喜欢,然后对其进行查询来做到这一点。

指数:

public class PostLikesPerDay : AbstractIndexCreationTask<Post, PostLikesPerDay.Result>
{
    public PostLikesPerDay()
    {
        Map = posts => from post in posts
                        from like in post.Likes
                        select new Result
                        {
                            Title = post.Title,
                            Date = like.Created,
                            Likes = 1
                        };

        Reduce = results => from result in results
                            group result by new
                            {
                                result.Title, 
                                result.Date.Date
                            }
                            into grp
                            select new Result
                            {
                                Title = grp.Key.Title,
                                Date = grp.Key.Date,
                                Likes = grp.Sum(l => l.Likes)
                            };
    }

    public class Result
    {
        public string Title { get; set; }
        public DateTime Date { get; set; }
        public int Likes { get; set; }
    }
}

和查询:

using (var session = store.OpenSession())
{
    var oneMonthAgo = DateTime.Today.AddMonths(-1);
    var query = session.Query<PostLikesPerDay.Result, PostLikesPerDay>()
                        .Where(y => y.Date > oneMonthAgo)
                        .OrderByDescending(p => p.Likes)
                        .Take(10);

    foreach (var post in query)
    {
        Console.WriteLine("'{0}' has {1} likes on  {2:d}", post.Title, post.Likes, post.Date);
    }
}
于 2013-03-10T08:00:53.147 回答