TL; DR:
Chat is one collection. ChatMess is another that has messages that link to Chat _id. How to get the latest messages from the chat list with fewer calculations? Here the find / fetch loop in the loop is too heavy and long.
I have this publication, which is used to return the cursor set to the user:
- Chats in which he takes part (from the chat collection)
- The last message from each chat session referenced by the first cursor (from the ChatMess collection)
Currently, the logic is as follows:
- Get a list of chat sessions from a user profile
- Find chat sessions and pass it through
- In a loop, I find the last message from this chat session and store its _id in an array. In addition, I save all other _ID users.
- Then I find messages that match the idid in my array.
Here is my main problem:
Is there a way to speed up getting the latest messages from each chat session? Using this algorithm, I easily reach 8000 ms response time, which is too complicated calculation time, since most of this time is spent searching / receiving chat messages _id (cf linked screen from Kadira).
Meteor.publish("publishNewChat", function() { this.unblock(); // we get a list of chat _id let chatIdList = _get_all_the_user_chats_ids(this.userId); if (!chatList) return ; // get the chat sessions objects let chats_cursor = Modules.both.queryGet({ type : 'chat', method : 'find', query : { _id: { $in: chatIdList } }, projection : { sort: { _id: 1 }, limit : 1000 } }); let array_of_fetched_chats = chats_cursor.fetch(); let chat_ids = []; // and here we loop through the chat documents in order to get the last message that been attached to each of them array_of_fetched_chats.forEach(function(e) { let lastMess = Modules.both.queryGet({ type : 'chatMess', method : 'findOne', query : { chatId: e._id }, projection : { sort: { date: -1 } } }); if (lastMess) chat_ids.push(lastMess._id); }); return ([ chats_cursor, Modules.both.queryGet({ type : 'chatMess', method : 'find', query : { _id: { $in: chat_ids } }, projection : { sort: { date: -1 }, limit: 1000 } }) ]); });
Finally, it also adds latency to all of my next DDP request. I am currently using this.unblock () to avoid this, but I would rather not use it here.
FYI, I have another publication that is updated every time the client changes the current active chat session: on the client, routing to a new chat adds its _id to the reactive array, which updates my getChatMess subscription to get messages from each chat, which the user visited in this since he connected. The goal, obviously, is to save on the server sending every message from every chat session that the user has visited in his life.
Unfortunately, I don't have enough ideas to improve this algorithm without breaking all my chat logic: S. Do you have any ideas? How are you?
Thanks.
EDIT: here is a screen from kadira that clearly shows the problem: 