RavenDB 4.2 Словарь Map-Reduce - PullRequest
2 голосов
/ 07 мая 2020

У меня есть набор сообщений чата, в котором есть список руководств, которые представляют собой участников, которые видели это сообщение.

Чтобы иметь возможность проверить количество непрочитанных сообщений в чате, я собираю их результаты, проверяя, сколько сообщений и сколько сообщений видел пользователь.

Первоначально я придумал этот индекс:

public class ChatMessages_BySeen : AbstractIndexCreationTask<ChatMessage, ChatMessages_BySeen.Result>
{
    public override string IndexName => nameof(ChatMessages_BySeen);

    public class Result
    {
        public string GroupId { get; set; } = null!;
        public IEnumerable<Guid> SeenBy { get; set; } = null!;
        public int Total { get; set; }
    }

    public ChatMessages_BySeen()
    {
        Map = messages => 
                            from message in messages
                            select new
                            {
                                GroupId = message.GroupId,
                                SeenBy = message.SeenBy.Select(x => x),
                                Total = 1
                            };

        Reduce = results =>
                            from result in results
                            group result by result.GroupId into g
                            select new
                            {
                                GroupId = g.Key,
                                SeenBy = g.SelectMany(x => x.SeenBy.Select(p => p)),
                                Total = g.Sum(x => x.Total)
                            };
    }
}

Но это быстро генерирует большой список повторяющихся пользователей идентификаторы. Поэтому вместо этого я подумал, вдохновленный { ссылка }, что я могу просто суммировать количество каждого члена ->

    public class ChatMessages_BySeen : AbstractIndexCreationTask<ChatMessage, ChatMessages_BySeen.Result>
{
    public override string IndexName => nameof(ChatMessages_BySeen);

    public class Result
    {
        public string GroupId { get; set; } = null!;
        public Dictionary<Guid, int> SeenCounter { get; set; } = null!;
        public int Total { get; set; }
    }

    public ChatMessages_BySeen()
    {
        Map = messages => 
                            from message in messages
                            select new
                            {
                                GroupId = message.GroupId,
                                SeenBy = message.SeenBy.ToDictionary(x => x, x => 1),
                                Total = 1
                            };

        Reduce = results =>
                            from result in results
                            group result by result.GroupId into g
                            select new
                            {
                                GroupId = g.Key,
                                SeenBy = g.SelectMany(x => x.SeenCounter).GroupBy(x => x.Key).OrderBy(x => x.Key).ToDictionary(x => x.Key, x => x.Sum(y => y.Value)),
                                Total = g.Sum(x => x.Total)
                            };
    }
}

, однако это всегда устанавливает SeenCounter как пустое / ноль. Может ли кто-нибудь помочь мне в правильном направлении?

...