TL;博士:
聊天是一个集合。ChatMess 另一个包含引用 Chat _id 的消息的消息。如何以尽可能少的计算从聊天列表中获取最后一条消息?在这里,循环中的查找/获取周期太重且太长。
我有这个出版物,用于向用户返回一组光标:
- 他参加的聊天会话(来自聊天收藏)
- 第一个光标中引用的每个聊天会话的最后一条消息(来自 ChatMess 集合)
目前,逻辑是:
- 从用户个人资料中获取聊天会话列表
- 找到聊天会话并循环播放
- 在循环中,我找到来自此聊天会话的最后一条消息,并将其 _id 存储在一个数组中。此外,我存储所有其他用户_id。
- 然后,我找到 _id 与我的数组中的消息匹配的消息。
这是我的主要问题:
难道没有一种更快的方法来从我的每个聊天会话中获取最后一条消息吗?使用该算法,我很容易达到 8000 毫秒的响应时间,这是一个过于繁重的计算时间,因为大部分时间都用于查找/获取聊天消息的 _id(参见 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's 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 }
})
]);
});
最后,它还为我随后的所有 DDP 请求添加了延迟。我目前使用 this.unblock() 来避免这种情况,但我不想在这里使用它。
仅供参考,我有另一个发布,每次客户端更改他当前的活动聊天会话时都会更新:在客户端上,路由到一个新的聊天将其 _id 添加到一个反应数组中,以更新我的 getChatMess 订阅,以便在客户端上获取消息从用户连接后访问的每个聊天中。目标显然是让服务器不必从用户一生中访问过的每个聊天会话中发送每条消息。
不幸的是,我缺乏在不破坏我所有聊天逻辑的情况下改进算法的想法:S。你有什么想法吗?你会怎么做?
谢谢。