检索发送者和接收者共享的消息 - chat mongodb, express, react
Posted
技术标签:
【中文标题】检索发送者和接收者共享的消息 - chat mongodb, express, react【英文标题】:Retrieving messages shared by the sender and receiver - chat mongodb, express, react 【发布时间】:2021-06-30 21:40:32 【问题描述】:我在 mongodb 数据库中有两个集合 students
和 teachers
。下面是学生和老师之间对话的示例结构。在学生和教师对象中,我有一个包含消息对象的messages
数组,以及包含发送和接收消息的人的id
的receiver
和sender
。我正在寻求有关创建什么功能来下载发送者和接收者的通用消息并将它们显示在发送者或接收方的建议,具体取决于发送者。如果是学生发送的,则在消息的左侧,如果是教师发送的消息,则在右侧。任何人都有材料解释如何做到这一点??
学生
"_id": "$oid": "600333" ,
"name": "MMMMMM",
"surname": "xxxxx",
"email": "mar@gmail.com",
"role": "student",
"messages": [
"contentInfo":
"viewed": false,
"msg": "22222222ghjk",
"createdAt": "$date": "$numberLong": ""
,
"_id": "$oid": "" ,
"receiver": "$oid": "5fea6e09"
,
"contentInfo":
"viewed": false,
"msg": "heloooo",
"createdAt": "$date": "$numberLong": ""
,
"_id": "$oid": "" ,
"receiver": "$oid": "5fea6e09"
,
"contentInfo":
"viewed": false,
"msg": "dfdfdf",
"createdAt": "$date": "$numberLong": ""
,
"_id": "$oid": "" ,
"receiver": "$oid": "600333"
]
教师
"_id": "$oid": "5fea6e09" ,
"isActiveTutor": false,
"youtubeUrlId": "",
"name": "rrrr",
"surname": "rrrrr",
"email": "u@gmail.com",
"initials": "",
"role": "tutor",
"createdAt": "$date": "" ,
"updatedAt": "$date": "$numberLong": "" ,
"messages": [
"contentInfo":
"viewed": false,
"msg": "22222222ghjk"
"createdAt": "$date": ""
,
"_id": "$oid": "" ,
"sender": "$oid": "600333"
,
"contentInfo":
"viewed": false,
"msg": "heloooo",
"createdAt": "$date": "$numberLong": ""
,
"_id": "$oid": "" ,
"sender": "$oid": "600333"
,
"contentInfo":
"viewed": false,
"msg": "dfdfdf",
"createdAt": "$date": "$numberLong": ""
,
"_id": "$oid": "" ,
"sender": "$oid": "5fea6e09"
]
【问题讨论】:
学生和教师的样本数据是否正确?因为在“msg”:“22222222ghjk”和“msg”:“heloooo”中,发件人是“600333”,那么收件人是谁?当您将所有消息保存在一个文档中并且聊天大小超过 16 MB 时,您会收到错误 @MohammadYaserAhmadi 这只是“假”结构。在这种情况下,关于你问。发送者是学生,接收者是导师。在您看来,IT 应该是什么样子? 【参考方案1】:我个人建议不要保存嵌套在对象上的消息,想象一下,对于一个有很多学生的老师来说,规模会以多快的速度爆炸。
对于玩具示例,这很好,但对于实际应用,您永远不应该这样做。
更常见的方法是以下两种之一:
-
(我的建议)是有一个单独的消息集合,每条消息都具有相同的结构:
created_time: Date,
sender_id: ObjectId,
receiver_id: ObjectId,
message: string
使用基于sender_id
和receiver_id
和created_time
的索引,这是最可扩展的解决方案,您还可以根据需要将旧消息“淘汰”到不同的集合中,例如聊天功能您可以获取两者之间的最后 x 条消息并允许加载更多消息,这可以通过 skip
和 limit
轻松完成。
-
创建一个“对话”集合,对话将以与学生/老师类似的方式保存嵌套消息,与您当前的结构相比,它的优势正如我之前解释的那样,一个有 30 个学生的老师将拥有它的消息数组爆炸,使从他那里查询/获取数据变慢。这样可以更好地管理它,但这种解决方案在一定程度上也有限制。
【讨论】:
您是否建议将所有消息 created_time: Date, sender_id: ObjectId, receiver_id: ObjectId, message: string 放在一个集合“消息”中?如何将“退休”旧消息放入另一个集合中。我必须从一个集合中删除并放入另一个集合,例如 30 天?但稍后我将不得不从两个集合中获取消息? 在很多地方都完成了退役或归档的目的,目标是在假设一年前的消息不相关/不经常访问的前提下,通过快速查询保持精益快速收集.是的,如果您这样做,您将不得不管理另一个集合。我只是建议它作为一个选项,您的应用可能不需要它,它可能不会达到超大规模。【参考方案2】:检查这个:https://getstream.io/blog/how-to-create-a-chat-app-with-angular-9/
这是一个 Angular 博客,但由于您已经拥有消息历史记录,因此您可以使用 html
和 css
来复制聊天功能,并根据发送消息的人在双方发送消息。
基本上,你可以copy-paste
代码,只需修改这部分:
<li class="message" *ngFor="let message of messages">
<div
*ngIf="
message.user.id !== currentUser.me.id;
then incoming_msg;
else outgoing_msg
"
></div>
<ng-template #incoming_msg>
<div class="incoming_msg">
<div class="incoming_msg_img">
<img
src="https://i.imgur.com/k2PZLZa.png"
/>
</div>
<div class="received_msg">
<div class="received_withd_msg">
<p> message.text </p>
</div>
</div>
</div>
</ng-template>
<ng-template #outgoing_msg>
<div class="outgoing_msg">
<div class="sent_msg">
<p> message.text </p>
</div>
</div>
</ng-template>
</li>
这部分的作用是遍历消息列表并检查消息是在左侧还是右侧。
假设如果Student
已登录,他可以选择打开与一些Teacher
的对话。在这种情况下,您将需要获取特定 Student
和特定 Teacher
之间的所有消息。您可以创建一个端点,该端点将返回当前用户和选定对话者的消息历史记录。为此,让我们创建一个端点,它将采用 current_user_id
、current_user_role
和 interlocutor_id
,并在此基础上返回 message-history
。
端点可能如下所示:
router.get('/message-history', (req, res, next) =>
const current_user_id, current_user_role, interlocutor_id = req.query;
if (current_user_role === 'student')
Students.findById(current_user_id).then((student) =>
let messages = student.messages.filter((message) => (message.sender == interlocutor_id || message.receiver== interlocutor_id));
res.status(200).json( success: true, messages: messages )
).catch((error) =>
res.status(404).json( success: false, message: 'User can not be found.' )
)
else
Teachers.findById(current_user_id).then((teacher) =>
let messages = student.messages.filter((message) => (message.sender == interlocutor_id || message.receiver== interlocutor_id));
res.status(200).json( success: true, messages: messages )
).catch((error) =>
res.status(404).json( success: false, message: 'User can not be found.' )
)
);
现在,当您拥有 message-history
数组时,您可以划分消息。如果消息具有receiver
属性,则可以将其放在一侧,如果消息具有sender
属性,则可以将其放在另一侧。
【讨论】:
我在问题中提到我有两个集合tutors
和`student`(我粘贴了代码示例)。如何在express, mongodb
中创建查询来检索这些消息?
我更新了答案。检查这是否适合您。
我们可以加入聊天吗?
在数据库 mongodb 中存储按摩的最佳方法是什么?我有对象老师和学生的消息。这是好方法吗?以上是关于检索发送者和接收者共享的消息 - chat mongodb, express, react的主要内容,如果未能解决你的问题,请参考以下文章