I've got a collection of chat messages, which have a list of guids which is the members who have seen this message.
To be able to check the unread message count per chat, i aggregate these results by checking how many messages there are vs how many messages the user have seen.
Originally i came up with this index:
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)
};
}
}
But this quickly generates a large list of duplicate user ids. So instead i thought, with some inspiration from https://stackoverflow.com/a/17499412/11388196 that i could just aggregate the count of each member ->
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)
};
}
}
this however, always sets the SeenCounter to be empty/null. Can anyone help me in the right direction?