Архитектура MongoDB: как хранить большое количество массивов или вложенных документов в масштабируемой форме - PullRequest
0 голосов
/ 14 марта 2020

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

Так что лучше структурировать мою базу данных следующим образом:

blog1 : {
 blogname : 'blog1',
 blogposts: [array of blogposts] 
},

blog2 : {
 blogname : 'blog2',
 blogposts: [array of blogposts] 
}

Или я должен создать отдельная коллекция со всеми постами блога, что-то вроде этого:

blogpost1: {
 id: 'blogpost1',
 content: {blogpost content in json format}
},
blogpost2: {
 id: 'blogpost2',
 content: {blogpost content in json format}
}

и ссылки на них в коллекции блогов.

Я хочу знать, какой выбор будет лучше при большом количестве постов в блогах. Потому что я помню, как читал где-то в документации MongoDB, что не рекомендуется иметь массивы внутри документа, которые могут выходить за границы, поэтому подход № 1 не идеален, верно?

Ответы [ 2 ]

1 голос
/ 14 марта 2020

При создании баз данных мне полезно подумать о запросах, которые я буду делать.

Пользователь приложения для ведения блога хотел бы выполнить поиск по всем блогам или найти блоггера по некоторым критериям.

В этом случае лучше всего подойдут отдельные коллекции для блогеров и блогов. Затем структурируйте свои документы так, чтобы блоггеры ссылались на свои блоги и наоборот.

Это можно сделать с помощью схем * Mon goose (https://mongoosejs.com/docs/index.html).

// models/blogger.js
const mongoose = require('mongoose')

const bloggerSchema = mongoose.Schema({
  blogs: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Blog'
    }
  ],
  name: String
})

bloggerSchema.set('toJSON', {
  transform: (document, returnedObject) => {
    const blogger = returnedObject

    blogger.id = blogger._id.toString()
    delete blogger._id
    delete blogger.__v
  }
})

module.exports = mongoose.model('Blogger', bloggerSchema)

Затем используйте заполнить свой запрос:

// controllers/bloggers.js
const bloggersRouter = require('express').Router()
const Blogger = require('../models/blogger')

bloggersRouter.get('/', async (request, response) => {
  const bloggers = await Blogger.find({}).populate(
    'blogs', {
      title: 1
    }
  )
  response.json(bloggers.map(blogger => blogger.toJSON()))
})

module.exports = bloggersRouter

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

Можно также подумать об ограничении длины блога, чтобы вы могли лучше контролировать данные, а затем подумать о вариантах, предложенных Джо.

0 голосов
/ 14 марта 2020

Почему это должен быть один или другой?

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

Хранение постов в отдельная коллекция хороша для больших постов и занятых блогов, но добавляет дополнительный запрос или поиск для извлечения.

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

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

Для занятых блогов: хранить их в архиве коллекции. Возможно, сохраните самую последнюю пару постов или самые популярные посты в документе блога, чтобы вам не приходилось каждый раз ссылаться на другую коллекцию.

Вам также необходимо выяснить, как разбивать пост между документами. MongoDB имеет ограничение в 16 МБ для одного документа, поэтому, если кто-то из ваших пользователей создает огромные записи, вам нужно будет где-то их хранить.

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

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