问题描述
我的聊天应用支持删除和编辑消息。对于这种方法,我设计了如下聊天模式。
架构
会员 | 线程 | 活动 |
---|---|---|
_id | _id | _id |
类型:private ,group
|
类型:private ,group
|
类型:message_deleted 、message_edited 、user_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 (将#修改为@)