2014-11-14 115 views
1

我试图将用户之间的私人消息添加到我的数据模型中。我一直在两种可能的方式之间来回切换。猫鼬私人聊天消息模型

1)每个用户都有一个user_id,chat_id对的数组,对应于他们参与的聊天。聊天模型只存储chat_id和消息数组。

2)不要与用户存储聊天,只要聊天模型存储一对user_ids和消息数组。

选项(1)的问题是每当用户加入或开始聊天时,我需要首先查看数组,以便用户查看user_id,chat_id对是否已存在。然后在Chat中再次找到chat_id。如果它不存在,我需要在两个不同的地方为正在参与的用户创建user_id,chat_id对。

使用选项(2)我将通过聊天模型搜索user_id1,user_id2对,如果我发现它,我完成了,如果没有,我会为该对创建一个新的聊天记录并完成。

基于这个选项(2)似乎是处理这个问题的更好方法。然而,我遇到了一些问题,想要解决如何在聊天模型中轻松搜索用户id的“对”。即,如果user_id以错误顺序传递,即user_id2,user_id1,我如何确保我可以找到聊天记录。在Mongoose中建模的最佳方式是什么?

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,以便他们总是参与者1 <参与者2例如,使搜索更简单?

+1

我想你会希望发件人如何拥有它,然后而不是'参与者1','参与者2'等,只是做'参与者:[{type:mongoose.Schema.Types.ObjectId,ref:' User'}]'这将给你一个用户数组,然后做一个搜索,你会做这样的事情'Chat.find({参与者:{$ in:{“数组名称”}},function(err,参与者){} – gmaniac 2014-11-14 19:21:22

+0

@gmaniac谢谢!我想我最终会做出与你所建议的非常相似的东西。$ in不起作用,因为这样做$或$但是$ all都可以用于这个我认为。 – 2014-11-15 03:19:57

+0

很高兴我可以帮助!如果你想更新你的问题,我们可以帮助你进一步或如果你找到你要找的答案并接受它 – gmaniac 2014-11-17 14:08:19

回答

3

一些建议。

首先 - 为什么存储Participant1和2作为数组?有一个特定发件人和一个(或多个)收件人(具体取决于是否需要群组消息)。

考虑以下模式:

var 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 } ] });

此架构允许一个聊天文件来存储所有信息,所有的参与者,并与每个消息,每个参与者都状态。

布尔is_group_message是过滤哪些是直接/组消息,可能是客户端查看或服务器端处理的简短方法。直接消息显然更容易用查询方式工作,但两者都非常简单。

meta数组列出了单个消息的每个参与者的传递/读取状态等。如果我们不处理组消息,这不需要是一个数组,但我们是,所以这很好。

deliveredread属性在主文档(而不是元子文档)上也是判断最后一条消息是否被传递/读取的简便方法。它们在每次写入文档时都会更新。

该模式允许我们将关于聊天的所有内容存储在一个文档中。即使是群组聊天。

+0

使用这种方法将使聊天效率低下分页 – Maysara 2017-12-01 16:04:28

+0

@Maysara我已经一世基于这种方法为生产聊天服务提供了更复杂的数据模式,如果需要的话,我可以花费一些时间并分享过程。任何选择都有一定的折衷。让每条消息单独存储然后再聚合它们看起来像是另一种对我来说没有多大意义的选择。 反向分页在任何聊天系统中都比较少见,当它发生时,分页到这个*实际*变得低效的地步实际上是非常罕见的。 – 2017-12-01 19:05:53

+0

@AugieGardner,我在建立一个聊天室,但是atm,我有一个会话模式和消息模式,他们有对话的ID。 您的模式看起来非常好,并防止来自MongoDB的多重查询。 你能告诉我你正在谈论的“更复杂”的模式吗? – Hightline 2017-12-24 00:01:58