如何使用MongoDB跟踪私人消息系统?

时间:2010-04-20 01:04:50

标签: mongodb

使用facebook的私人消息系统,您必须跟踪发送者和接收者以及消息内容。如果我使用的是MySQL,我会有多个表,但是对于MongoDB,我会尽量避免这一切。我正在努力想出一个可以扩展并且易于维护的“好”模式。如果我使用的是mysql,我会有一个单独的表来引用用户和消息。见下文......

个人资料表

user_id
first_name
last_name

消息表

message_id
message_body
time_stamp

user_message_ref表

user_id (FK)
message_id (FK)
is_sender (boolean)

使用上面列出的架构,我可以查询“Bob”可能拥有的任何消息,无论他是收件人还是发件人。

现在如何将其转换为适用于MongoDB的模式。我想我会有一个单独的集合来保存消息。问题是,我如何区分发件人和收件人?如果Bob登录,我该查询什么?根据Bob是否发起了电子邮件,我不想查询“发件人”和“收件人”,只是为了查看邮件是否属于用户。

我点击了MongoDB的消息组,并找到了可行的方法。 每条消息都将被视为“博客”帖子。创建消息时,将两个用户(无论最初发送者/接收者最初)添加到数组中。之后的每个响应都将被视为注释,它将被插入到数组中。

MESSAGES

{
    "_id" : <objectID>,
    "users" : ["bob", "amy"],
    "user_msgs" :
        [
            { 
                "is_sender" : "bob",
                "msg_body" : "Hi Amy, how are you?!",
                "timestamp" : <generated by Mongo>
            }
            { 
                "is_sender" : "amy",
                "msg_body" : "Bob, long time no see, how is the family?!",
                "timestamp" : <generated by Mongo>
            }
        ]
}

这样我可以查询涉及“Bob”的消息,并遍历“user_msgs”数组。我将能够告诉发件人是谁,并按时间戳排序。

3 个答案:

答案 0 :(得分:2)

想出来。请参阅上面原始帖子中的解释。

答案 1 :(得分:1)

您需要在两个集合(用户和消息)之间建立某种链接。

就个人而言,我会保持简单,并添加两个额外的字段来跟踪发件人和收件人的ID,如下所示:

{
    _id: /* whatever_id */,
    message_body: "This is the message",
    date_sent: 2010-04-20T10:35,
    sender_id: /*id_of_sender*/,
    recipient_id: /* id_of_recipient */
}

sender_idrecipient_id字段只会为相应的用户(很可能是某个ObjectID实例保留值,尽管您可以分配任何您喜欢的内容),这对应于_id字段用户集合中的相应条目。您可以适当地查询这些信息以获取您所追踪的信息(或计算它们或其他任何信息)。

另一种方法可能是有效地做同样的事情,但是对发送者和收件人使用正式的DBRef而不是仅仅将他们的ID放入。这可能也会起作用但我倾向于使用之前的解决方案只是因为它更简单,可能更容易查询。

两个解决方案都需要再次往返数据库以获取相应的用户文档(例如,用于显示“from”和“to”名称)。


修改
看起来我误解了你想要实现的目标 - 我不知道Facebook消息包含了任何线程概念。但是,您在上面介绍的解决方案看起来很合理。就个人而言,我会为用户而不是他们的名字(alice&amp; bob)添加ID,但除此之外看起来相当可行。

答案 2 :(得分:1)

Your Db Schema Should be like this->

let chatImages = {
    original  : {type:String,required:true,trim:true},
    thumbnail : {type:String,required:true,trim:true}
};

let Chats = new Schema({
    CommonId  : {type: String, trim: true, index: true, unique: true,sparse: true},
    senderId   : {type: Schema.Types.ObjectId,index: true,required:true,ref:'User'},
    receiverId : {type: Schema.Types.ObjectId,index: true,required:true,ref:'User'},
    messageId  : {type: String, trim: true, index: true, unique: true,sparse: true},
    isDeliver  : {type: Boolean, default: false},
    isSent     : {type: Boolean, default: true},
    chatType   : {
                 type: String,required:true,enum: [
                 Config.APP_CONSTANTS.DATABASE.CHAT_TYPE.TEXT,
                 Config.APP_CONSTANTS.DATABASE.CHAT_TYPE.IMAGE
                 ],default:Config.APP_CONSTANTS.DATABASE.CHAT_TYPE.TEXT},
    text       : {type: String, trim: true, index: true,sparse: true},
    sentAt     : {type:Number, default: Date.now,index:true,required: true},
    chatImage  : {type:chatImages},
});

如果您想要像whatsApp这样的屏幕,您可以看到与您聊天的人,CommonId非常重要。 1)它使分组非常容易(使用$ groupBy)。

你可以只通过在receiverId和SenderId之间进行比较来生成CommonId,这是提升它的CommonId

我认为这是一个很好的解释