public async Task <List <ChatConversation> > GetUnReadChatConversationsAsync(string app_Id, string chatId, string userId)
        {
            try {
                var chat = await _chats.Find <Chat> (c => c.AppId == app_Id && c.Id == chatId)
                           //.Project<Chat>(Builders<Chat>.Projection
                           //.Slice(c => c.ChatConversations.Find(conv => conv.UserId!=userId && !conv.ChatConversationReaders.Any(reader => reader.UserId == userId)),0)).FirstOrDefaultAsync();
                           .FirstOrDefaultAsync();

                var query = from conversation in chat.ChatConversations.AsQueryable()
                            where conversation.UserId != userId && !conversation.ChatConversationReaders.Any(reader => reader.UserId == userId)
                            join user in _users.AsQueryable() on
                            conversation.UserId equals user.Id into ConversationUser
                            orderby conversation.Date descending
                            select new ChatConversation()
                {
                    Id     = conversation.Id,
                    UserId = conversation.UserId,
                    Text   = conversation.Text,
                    FileId = conversation.FileId,
                    Date   = conversation.Date,
                    ParentConversationId    = conversation.ParentConversationId,
                    ChatConversationReaders = conversation.ChatConversationReaders,
                    User = ConversationUser.Select(conversationUser => new User()
                    {
                        Id = conversationUser.Id, FullName = conversationUser.FullName
                    }).FirstOrDefault()
                };
                return(await Task.FromResult(query.Reverse().ToList()));
            } catch (Exception ex) {
                _logger.LogError(ex, "GetUnReadChatConversationsAsync ChatRepository Exception");
                return(null);
            }
        }
        public async Task <List <ChatConversation> > GetChatConversationsAsync(string app_Id, string chatId, int pageIndex, int pageSize)
        {
            try {
                var chat = await _chats.Find <Chat> (c => c.AppId == app_Id && c.Id == chatId).Project <Chat> (Builders <Chat> .Projection
                                                                                                               .Slice("ChatConversations", (pageIndex * pageSize), pageSize)).FirstOrDefaultAsync();

                var query = from conversation in chat.ChatConversations.AsQueryable()
                            join user in _users.AsQueryable() on
                            conversation.UserId equals user.Id into ConversationUser
                            orderby conversation.Date descending
                            select new ChatConversation()
                {
                    Id     = conversation.Id,
                    UserId = conversation.UserId,
                    Text   = conversation.Text,
                    FileId = conversation.FileId,
                    Date   = conversation.Date,
                    ParentConversationId    = conversation.ParentConversationId,
                    ChatConversationReaders = conversation.ChatConversationReaders,
                    User = ConversationUser.Select(conversationUser => new User()
                    {
                        Id = conversationUser.Id, FullName = conversationUser.FullName
                    }).FirstOrDefault()
                };
                return(await Task.FromResult(query.Reverse().ToList()));

                //return await Task.FromResult(query.Skip(pageIndex * pageSize).Take(pageSize).ToList());
            } catch (Exception ex) {
                _logger.LogError(ex, "GetChatConversationsAsync ChatRepository Exception");
                return(null);
            }
        }
        public async Task <List <ChatConversation> > GetChatConversationsAsync(ChatHistoryFilterModel filter)
        {
            try {
                /* TO DO
                 *  optimize the query with aggregation framework*/
                var chat = await _chats.Find(c => c.Id == filter.ChatId).FirstOrDefaultAsync();

                if (filter.DirectionType == KeysetFilterModelType.Next)
                {
                    chat.ChatConversations = chat.ChatConversations
                                             .Where(conversation => conversation.Date.CompareTo(filter.EdgeDateTime) > 0)
                                             .OrderBy(o => o.Date).Take(filter.Limit).ToList();
                }
                else
                {
                    chat.ChatConversations = chat.ChatConversations
                                             .Where(conversation => conversation.Date.CompareTo(filter.EdgeDateTime) < 0)
                                             .OrderByDescending(o => o.Date).Take(filter.Limit).Reverse().ToList();
                }
                var query = from conversation in chat.ChatConversations.AsQueryable()
                            join user in _users.AsQueryable() on
                            conversation.UserId equals user.Id into ConversationUser
                            select new ChatConversation()
                {
                    Id     = conversation.Id,
                    UserId = conversation.UserId,
                    Text   = conversation.Text,
                    FileId = conversation.FileId,
                    Date   = conversation.Date,
                    ParentConversationId    = conversation.ParentConversationId,
                    ChatConversationReaders = conversation.ChatConversationReaders,
                    User = ConversationUser.Select(conversationUser => new User()
                    {
                        Id = conversationUser.Id, FullName = conversationUser.FullName
                    }).FirstOrDefault()
                };
                return(await Task.FromResult(query.ToList()));

                //return await Task.FromResult(query.Skip(pageIndex * pageSize).Take(pageSize).ToList());
            } catch (Exception ex) {
                _logger.LogError(ex, "GetChatConversationsAsync ChatRepository Exception");
                return(null);
            }
        }