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 に答える