MongoDB 聊天模式和查询

问题描述

我的聊天应用支持删除和编辑消息。对于这种方法,我设计了如下聊天模式。

架构

会员 线程 活动
_id _id _id
类型:privategroup 类型:privategroup 类型:message_deletedmessage_editeduser_kicked
user_id 被毁了 thread_id
thread_id 标题present when the type is 'group' to_user_id only for private chats
踢了 updated_at message_id present when the type is 'message_deleted','message_edited',...
user_id present when the type is 'user_kicked' who was kicked?
删除 created_at

为了更清楚,我没有添加 User 架构,当用户加入 Thread 时,会创建一个 Member 文档及其 user_id 和线程的id 为 thread_id

我将 message_deleted message_edited user_kicked 之类的事件存储在 event 集合中。当用户上线时,应用程序从数据库获取新事件并更改内容。这对于私人聊天很容易。我通过 user_id 并使用上次事件的 created_at 时间戳获取最近的事件。

Event.aggregate([
  {
    $match: { 
      to_user_id: MY_USER_ID,created_at: {
        $gt: LAST_TIMESTAMP
      }
    }
  }
]);

但是对于群聊 to_user_id 是没有用的。我无法为聊天中的每个成员创建新文档/记录。假设单个 message_edited 事件有 1,000,000 名成员和 1,000 条记录!


即使将接收者 id 存储在嵌套数组中也很糟糕。

{
  _id: ObjectId("507f1f77bcf86cd799439011"),type: "message_deleted",thread_id: ObjectId("5349b4ddd2781d08c09890f3"),to_user_id: [1,2,3,4,...],// receivers

  message_id: ObjectId("5349b4ddd2781d08c09890f4"),created_at: 1610786677445
}
const events = await Event.aggregate([
  {
    $match: {
      to_user_id: {
        $in: MY_USER_ID
      },created_at: {
        $gt: LAST_TIMESTAMP
      }
    }
  }
]);

我尝试使用另一个查询获取 thread_id,然后通过它们获取事件。

let thread_ids = await Member.find({
  user_id: MY_USER_ID,},'thread_id');

thread_ids = thread_ids.map(item => item.thread_id); // converts { thread_id: X } to X

const events = await Event.aggregate([
  {
    $match: {
      thread_id: {
        $in: thread_ids
      },created_at: {
        $gt: LAST_TIMESTAMP
      }
    }
  }
]);

这种方法存在问题,首先例如我有数千个组,thread_ids获取所有组,然后将它们以数组形式传递给 Event,这实在是太多了。

第二,假设管理员在 2 小时前把我踢出去了,我要上网,无论 2 小时的间隔如何,我都会收到聊天的所有最近事件,我不能被允许获得这些事件在我被踢之后。

遇到问题怎么办?我可以尝试另一个推荐的架构!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)