MongoDB - Mongoose: структура / архитектура документа

У меня относительно простой вопрос, но я снова и снова застреваю. Я думаю, что это четвертый раз, когда я пытаюсь реструктурировать свои документы, чтобы попытаться получить желаемый результат.

Я хочу создать базу данных в мангусте со следующей структурой:

У пользователя много групп, сообщений и комментариев. Все группы, сообщения и комментарии принадлежат пользователю. Сообщение может принадлежать множеству групп или ни одной. И комментарий принадлежит определенному сообщению.

Вот что у меня есть на данный момент:

UserSchema

var userSchema = mongoose.Schema({

    local            : {
        email        : String,
        password     : String,
        username     : String,  
        created: {type:Date, default: Date.now} 

    }

});

PostSchema

var PostSchema   = new Schema({
    url: String, 
    highlighted: String, 
    comment: String, 
    image: String, 
    timeStamp: String, 
    description: String, 
    title: String,
    created: {type:Date, default: Date.now}, 
    private: Boolean, 
    favorite: Boolean, 
    readlater: Boolean, 
    postedBy: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    },
    comments: [{
        text: String,
        postedBy: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'User'
        }
    }], 
    groups: [{
        name: String,
        postedBy: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'User'
        }
    }]
});

groupSchema

var GroupSchema = Schema({
    name    : String, 
    created: {type:Date, default: Date.now},
    postedBy: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    }
});

Хотя я могу ошибаться в этом предположении, я думаю, что у меня есть сообщение для пользователя и комментарий, чтобы опубликовать отношения такими, какими они должны быть. Пожалуйста, поправьте меня, если я ошибаюсь. Основная проблема, с которой я сейчас сталкиваюсь, - это то, что моя группа публикует сообщения об отношениях. В настоящее время отношений нет вообще. Насколько я могу, это почти как если бы группа принадлежит посту, а не наоборот. Единственный другой способ структурировать группу, который я могу придумать, - это так:

var GroupSchema = Schema({
        name    : String, 
        created: {type:Date, default: Date.now},
        postedBy: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'User'
        }, 
        posts: [{
            title: String, 
            Url: String,
            comments: [{
                text: String
            }]
            etc....
        }]
    });

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

Если вы можете дать какой-либо совет относительно того, как это должно быть структурировано, это мне очень поможет.

Заранее спасибо.


person Joshua L.    schedule 26.11.2015    source источник
comment
Я думаю, что вы застряли, потому что ни mongo (или, по сути, mongoose) не дает возможности кратко выразить реляционные данные. Есть ли причина, по которой вы не используете реляционную базу данных?   -  person Jonah Williams    schedule 26.11.2015
comment
Привет @Jonah. Я использую mongoDb / mongoose, потому что пытаюсь изучить средний стек. Что касается отношений, я уверен, что действительно можно делать то, что я прошу, используя DBrefs, или я ошибаюсь?   -  person Joshua L.    schedule 26.11.2015
comment
Вы структурируете свои данные так, как если бы они были реляционными - рассматривали ли вы просто встраивание групп и комментариев в сообщение? У вас есть 16 МБ свободного места.   -  person Jonah Williams    schedule 26.11.2015
comment
@JonahWilliams, да, есть, к чему я сейчас склоняюсь. Меня больше всего беспокоит то, как я могу ссылаться на это позже. Я хотел бы вытащить все сообщения, которые находятся внутри определенной группы, и, встраивая группы в сообщение, я борюсь с тем, как бы я сделал этот вызов базы данных. Не могли бы вы рассказать об этом?   -  person Joshua L.    schedule 26.11.2015
comment
@JoshuaL .: DBRef - это просто прославленные идентификаторы объектов. Они никоим образом не облегчают выполнение запросов. Они полезны, когда объект может ссылаться на разные типы объектов в одном и том же поле (например, сообщение имеет контент, и этим содержимым может быть видео, изображение, текст и т. Д.). Насколько я понимаю из схемы выше, вам это не нужно.   -  person Sergio Tulentsev    schedule 26.11.2015


Ответы (1)


Лучше всего встроить схемы групп и комментариев в документ публикации. Например,

var GroupSchema = Schema({
    name: String, 
    created: { type:Date, default: Date.now },
});

var CommentSchema = Schema({
    text: String,
    postedBy: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    }
});


var PostSchema = new Schema({
    url: String,
    ...,
    postedBy: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User'
    },
    comments: [CommentSchema] 
    groups: [GroupSchema]
});

Теперь, если вы ищете сообщения с определенной группой, вы можете создать запрос следующим образом. Однако вы можете создавать более сложные запросы, чем этот.

Post.elemMatch("groups", {name: {$in: ["group1", "group2"]}}).then(...)
person Jonah Williams    schedule 26.11.2015
comment
Здравствуйте, большое спасибо за ваш ответ. У меня есть еще один вопрос. Как может выглядеть запрос при извлечении списка всех групп? Это должен быть список всех уникальных групп в нескольких сообщениях, принадлежащих определенному пользователю. - person Joshua L.; 26.11.2015
comment
если это более распространенный запрос, я предлагаю также встраивать группы внутри пользователя. Несмотря на то, что это кажется ненужным дублированием, базы данных документов на самом деле все о денормализованных данных. - person Jonah Williams; 26.11.2015
comment
Привет, это кажется хорошей идеей. Мне понадобится способ передать данные группы при сохранении из post.group в user.group. Таким образом данные синхронизируются. Вы бы знали, как это сделать? Или другой способ синхронизации групп? - person Joshua L.; 26.11.2015
comment
Я думаю о такой простой вещи, как user.groups.push(post.group); user.save(callback); - person Joshua L.; 26.11.2015