Node.js Mongoose私有聊天消息模型
我正在尝试将用户之间的私有消息添加到我的数据模型中。我一直在两种可能的方法之间来回奔波 1) 每个用户都有一组用户id、聊天id对,它们对应于他们正在参与的聊天。聊天模型只存储聊天id和消息数组 2) 根本不存储与用户的聊天,只让聊天模型存储一对用户ID和消息数组 选项(1)的问题是,每当用户加入或开始聊天时,我都需要首先查看用户的数组,以查看用户id、聊天id对是否已经存在。然后在chat中再次查找聊天室id。如果它不存在,我需要在两个不同的地方为参与的两个用户创建用户id、聊天id对 使用选项(2),我将在聊天模型中搜索用户_id1、用户_id2对,如果找到,我就完成了,如果没有,我将为该对创建一个新的聊天记录并完成 基于此选项(2)似乎是更好的处理方法。然而,我遇到了一些问题,比如如何以一种在聊天模型中可以轻松搜索的方式对“一对”用户ID进行建模。i、 e.如何确保即使用户ID以错误的顺序传递,也能找到聊天记录,即用户ID 2、用户ID 1。在猫鼬身上建立模型的最佳方式是什么Node.js Mongoose私有聊天消息模型,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我正在尝试将用户之间的私有消息添加到我的数据模型中。我一直在两种可能的方法之间来回奔波 1) 每个用户都有一组用户id、聊天id对,它们对应于他们正在参与的聊天。聊天模型只存储聊天id和消息数组 2) 根本不存储与用户的聊天,只让聊天模型存储一对用户ID和消息数组 选项(1)的问题是,每当用户加入或开始聊天时,我都需要首先查看用户的数组,以查看用户id、聊天id对是否已经存在。然后在chat中再次查找聊天室id。如果它不存在,我需要在两个不同的地方为参与的两个用户创建用户id、聊天id对 使用选
var chatSchema = mongoose.Schema({
messages: [{
text: {
type: String,
max: 2000
},
sender: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
}],
participant1: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}]
participant2: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}]
});
如果是上面这样,我将如何搜索参与者对?我能否以某种方式对参与者ID进行排序,使其始终是参与者1var ChatSchema = new Schema({
sender : {
type : mongoose.Schema.Types.ObjectId,
ref : 'User'
},
messages : [
{
message : String,
meta : [
{
user : {
type : mongoose.Schema.Types.ObjectId,
ref : 'User'
},
delivered : Boolean,
read : Boolean
}
]
}
],
is_group_message : { type : Boolean, default : false },
participants : [
{
user : {
type : mongoose.Schema.Types.ObjectId,
ref : 'User'
},
delivered : Boolean,
read : Boolean,
last_seen : Date
}
]
});
此模式允许一个聊天文档存储所有消息、所有参与者以及与每条消息和每个参与者相关的所有状态
Boolean is_group_消息只是筛选直接/组消息的较短方法,可能用于客户端查看或服务器端处理。直接消息显然更容易处理查询,但两者都非常简单
meta
数组列出了单个消息的每个参与者的传递/读取状态等。如果我们不处理组消息,这不需要是一个数组,但我们是,所以这很好
主文档(不是元子文档)上的delivered
和read
属性也只是判断最后一条消息是否已传递/读取的速记方式。每次写入文档时都会更新它们
这个模式允许我们将聊天的所有内容存储在一个文档中。甚至是小组聊天。这个问题没有正确的答案,但你提到的方法肯定不是最好的 首先,当您考虑设计“聊天”模式时,需要考虑到用户之间会有数百万条消息,因此在获取聊天时需要考虑性能。 <>将消息存储到数组中不是一个好主意,你的模型的大小会很大,你必须考虑MunGDB的文档大小限制当前是每份文档16 MB。
<强>第二,您必须考虑分页方面,因为这会影响聊天时的性能,当您检索2个用户之间的聊天时,您不会要求从开始的所有聊天,您只需要最近的一个,然后您可以请求旧的,如果用户滚动聊天,这一方面非常重要,由于其对性能的影响,不可忽视。
我的方法是将每条消息存储在一个单独的文档中 首先,将每条消息存储在单个文档中可以提高获取聊天记录时的性能,并且文档的大小非常小 这是一个非常简单的示例,您需要根据您的需要更改模型,这只是为了表示想法: 您可以通过以下查询获取聊天记录: 简单干净!正如您所看到的,使用这种方法分页变得非常容易。我认为您应该希望发送者了解您的情况,而不是执行
participant1
,participant2
等操作。只需执行参与者:[{type:mongoose.Schema.Types.ObjectId,ref:'User'}]
这将为您提供一个用户数组,然后要进行搜索,您可以执行以下操作Chat.find({participants:{$in:{“array of names”}},function(err,participants){}
@gmaniac谢谢!我想我最终会做一些与你建议的非常类似的事情。$in不起作用,因为$in不起作用,但我认为$all对这一点起作用。很高兴我能提供帮助!如果你想更新你的问题,我们可以进一步帮助你,或者如果你找到了你想要的答案并接受它。请使用此appr检查此问题oach将对聊天进行分页inefficient@Maysara我已经基于此方法为生产聊天服务实现了一个更复杂的数据模式,如果有人要求,我可以花一些时间和大家分享这个过程。当然,任何选择都会有折衷。将每条消息单独存储,然后将其聚合似乎是另一种选择另一种对我来说没有多大意义的方法。反向分页在任何聊天系统中都比较少见,而且当这种情况发生时,分页到实际上变得效率低下的程度是非常非常罕见的。@AugieGardner,我正在建立一个聊天室,但atm,我有一个会话模式和消息模式,他们有会话的ID。您的模式看起来非常好,可以防止来自MongoDB的多个查询。您能告诉我您正在谈论的“更复杂”的模式吗
const MessageSchema = mongoose.Schema({
message:{
text: { type:String, required:true }
// you can add any other properties to the message here.
// for example, the message can be an image ! so you need to tweak this a little
}
// if you want to make a group chat, you can have more than 2 users in this array
users:[{
user: { type:mongoose.Schema.Types.ObjectId, ref:'User', required:true }
}]
sender: { type:mongoose.Schema.Types.ObjectId, ref:'User', required:true },
read: { type:Date }
},
{
timestamps: true
});
Message.find(({ users: { "$in" : [#user1#,#user2#]} })
.sort({ updatedAt: -1 })
.limit(20)