В настоящее время я использую небольшой дочерний документ для ссылки на другие коллекции:
{ name: 'xxx', id: 'xxx'}
.. вместо ручной ссылки.
Итак, для сообщения на форуме я мог бы иметь это:
{
title: 'Some title',
creator: { name: 'jgauffin', id: ObjectId(123445455) },
posts: [...]
}
Причина в том, что мне не нужно выполнять поиск в других коллекциях каждый раз, когда я получаю документ, и имена почти не меняются.
Но поскольку я новичок в этом, существуют ли для этого какие-либо устоявшиеся шаблоны проектирования? Или вы должны выполнять $lookup даже для одного поля в других коллекциях?

Прежде всего: «{ name: 'xxx', id: 'xxx'} .. вместо справочника по руководству».
Это ручная ссылка, и это рекомендуемый способ. т. е. поле, которое имеет ObjectId или любой другой тип, который вы используете в качестве _id в целевой коллекции:
Ссылка в руководстве — это практика включения поля
_idодного документа в другой документ. Затем приложение может выполнить второй запрос для разрешения ссылочных полей по мере необходимости.
Другой вариант — DBRef , для которого в документации сказано использовать ручные ссылки, если вам не нужно ссылаться на несколько коллекций.
Существуют ли какие-либо устоявшиеся шаблоны проектирования для этого?
Да, главное правило: «данные, к которым осуществляется общий доступ, должны храниться вместе». Поэтому, если вы отображаете сообщения на форуме с заголовком, именем пользователя и ссылкой на их профиль, и это происходит часто, то это правильный вариант.
Я бы добавил полное имя (если оно отображается) и ссылку на профиль, если оно не генерируется автоматически в HTML/JS непосредственно из имени пользователя как /user/<name> или из ObjectId как /profile/<id.toString()>.
Что касается обработки пользователем, меняющего свое имя пользователя или полное имя, это должно быть сделано в коде приложения. Итак, вы обновите имя пользователя, а затем установите updateMany() во всех затронутых коллекциях с помощью:
forum_posts.updateMany(
{ creator.id: ObjectId(12345) },
{ creator.name: "newname" }
)
Как вы уже сказали, «имена почти не меняются», и это нормально.
В случае огромного размера томов или архитектуры, управляемой событиями, вы можете обрабатывать эти обновления с помощью бессерверных функций или отдельных серверных служб, а также частями.
И делайте $lookup, когда вам это нужно, но избегайте шаблонов там, где это вам нужно часто. При правильном использовании все в порядке, если не злоупотреблять.
Массивы вложенных документов:
Следующая часть — поле posts: [...]. Наличие неограниченных массивов является антипаттерном. Рекомендуется ограничить массивы вложенных документов до 200. А затем поместить оставшиеся в отдельную коллекцию more_posts, в каждой из которых будет храниться 200. Существуют варианты в зависимости от использования. Вы можете иметь all_posts как документы размером 200, а затем хранить 50 самых «горячих» в коллекции forum или самые последние 20; как вы на самом деле его используете.
Схема согласно использованию, а не согласно данным
В MongoDB и других базах данных NoSQL ваша схема должна соответствовать вашему шаблону использования, а не «идеальной нормализованной форме». Это включает в себя дублирование некоторых данных в нескольких местах, если к ним часто обращаются одновременно. Если у вас есть опыт работы с RDBMS/SQL, может возникнуть соблазн сразу перейти на 3NF/5NF и т. д. Это самый распространенный антипаттерн. Другой вариант — противоположный: хранить все данные вместе, а не в том порядке, в котором они наиболее доступны.
Официальная документация
Я бы порекомендовал официальную документацию, поскольку ответы, основанные на мнениях, подобные этому 😂, могут оказаться противоречивыми:
200Короткий ответ: Да, этот подход соответствует основополагающему принципу: данные, к которым осуществляется совместный доступ, хранятся вместе. Этот принцип реализуется путем создания агрегатов данных. Один агрегат данных полностью представляет собой одну транзакцию. Образец документа, которым вы поделились, и прилагаемые к нему подробные сведения являются яркими примерами согласования с моделированием агрегатов данных.
Подробный ответ: Как мы знаем, хотя данные нормализованы, это обеспечивает лучшее обслуживание данных, но в то же время усложняет доступ к данным. Денормализованные данные работают противоположным образом: они затрудняют обслуживание данных; по-прежнему облегчает доступ к данным. Таким образом, каждый подход полностью зависит от контекста. Предположим, что контекст благоприятствует денормализованным данным, тогда у нас есть совпадение для дальнейшего обсуждения.
Используя реляционную модель данных, насколько мы можем денормализовать данные. Конечно, существует ограничение, поскольку строка в реляционной модели данных может хранить только простые данные и не может содержать вложенную структуру данных. Более того, строка не представляет собой реальную транзакцию. Реальная транзакция включает в себя множество строк данных. Эти присущие реляционной модели данных ограничения приводят к созданию моделей данных, ориентированных на агрегирование.
Чтобы извлечь максимальную выгоду из денормализации данных, необходимо создать наилучшие агрегаты данных. Агрегат данных — это полное представление реальной транзакции. При одном доступе становятся доступными все данные, связанные с транзакцией. Как упоминалось вначале, руководящим принципом создания агрегата данных является то, что «данные, к которым осуществляется общий доступ, хранятся вместе». Таким образом, вместо строки или набора строк единицей данных стал единый агрегат данных. Это одна и та же единица данных для хранения, извлечения и даже для распространения или сегментирования. Атом данных становится определяемым пользователем агрегатом данных. Модели данных семейства документов и столбцов основаны на подходе агрегирования данных.
Кроме того, при агрегировании данных устраняется несоответствие импедансов, поскольку разработчики могут видеть данные и взаимодействовать с ними в той же форме или структуре, в которой они представлены конечным пользователям. В некотором смысле агрегаты данных должны снизить накладные расходы на использование инструментов ORM. Агрегация данных делает кластерные вычисления практичными, что приводит к горизонтальному масштабированию вычислительных ресурсов.
В двух словах о подходе к агрегации данных: наименьшая единица данных — атом данных — становится определяемым пользователем агрегатом данных.