Как отслеживать частную систему обмена сообщениями с использованием MongoDB? - PullRequest
12 голосов
/ 20 апреля 2010

Возьмите систему личных сообщений Facebook, где вы должны отслеживать отправителя и получателя вместе с содержимым сообщения. Если бы я использовал MySQL, у меня было бы несколько таблиц, но с MongoDB я постараюсь избежать всего этого. Я пытаюсь придумать «хорошую» схему, которая может масштабироваться и проста в обслуживании. Если бы я использовал mysql, у меня была бы отдельная таблица для ссылки на пользователя и сообщение. Смотри ниже ...

таблица профилей

user_id
first_name
last_name

таблица сообщений

message_id
message_body
time_stamp

user_message_ref table

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

Используя схему, указанную выше, я могу запрашивать любые сообщения, которые может иметь «Боб», независимо от того, является ли он получателем или отправителем.

Теперь, как превратить это в схему, которая работает с MongoDB. Я думаю, у меня будет отдельная коллекция для хранения сообщений. Проблема в том, как я могу различить отправителя и получателя? Если Боб входит в систему, к чему я обращаюсь? В зависимости от того, инициировал ли Боб электронное письмо, мне не нужно запрашивать «отправитель» и «получатель», чтобы посмотреть, принадлежит ли сообщение пользователю.

Я включил группу сообщений MongoDB и ушел с чем-то, что может работать. Каждое сообщение будет рассматриваться как пост в блоге. Когда сообщение создано, добавьте двух пользователей (независимо от того, кто изначально был отправителем / получателем) в массив. Каждый ответ после этого будет рассматриваться как комментарий, который будет вставлен в массив.

СООБЩЕНИЯ

{
    "_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 ]

2 голосов
/ 24 апреля 2010

Разобрался. Смотрите мое объяснение выше в оригинальном сообщении.

1 голос
/ 03 июня 2018
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},
});

CommonId очень важен, если вам нужен экран наподобие whatsApp, где вы можете видеть людей, с которыми вы общаетесь. 1) Это делает группировку очень простой (с $ groupBy).

Вы можете сгенерировать CommonId, просто сравнив приемник и SenderId по возрастанию, положив CommonId

Я думаю, это хорошее объяснение

1 голос
/ 20 апреля 2010

Вам понадобится какая-то связь между двумя коллекциями (пользователи и сообщения).

Лично я хотел бы сохранить простоту и добавить два дополнительных поля для отслеживания идентификатора отправителя и получателя, что-то вроде этого:

{
    _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_id и recipient_id будет просто храниться значение для соответствующего пользователя (скорее всего, некоторый экземпляр ObjectID , хотя вы можете назначить все, что захотите), которое соответствует полю _id для соответствующего записи в коллекции пользователей. Вы сможете запросить их соответствующим образом, чтобы получить нужные вам сообщения (или сосчитать их, или что-то еще).

Другой подход может заключаться в том, чтобы эффективно сделать то же самое, но использовать формальный DBRef для отправителя и получателя, а не просто вводить их идентификаторы. Это, вероятно, будет работать так же хорошо, но я бы склонны использовать предыдущее решение только потому, что его проще и, вероятно, проще запрашивать.

Оба решения должны будут выполнить еще одну обратную передачу в БД, чтобы получить соответствующие пользовательские документы (например, для отображения имен «от» и «до»).


Edit:
Похоже, я неправильно понял, чего вы пытаетесь достичь - я не знал, что в сообщениях Facebook есть какая-то концепция потоков. Тем не менее, решение, которое вы представили выше, выглядит обоснованным. Лично я бы указывал идентификаторы пользователей, а не их имена (alice & bob), но, кроме этого, это выглядит вполне работоспособным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...