Поддокументы Mongoose против вложенной схемы
Мне любопытно относиться к плюсам и минусам использования поддокументов и более глубокого слоя в моей основной схеме:
var subDoc = new Schema({
name: String
});
var mainDoc = new Schema({
names: [subDoc]
});
или
var mainDoc = new Schema({
names: [{
name: String
}]
});
В настоящее время я использую поддоки, но мне интересно в первую очередь о производительности или запросах, с которыми я мог столкнуться.
Ответы
Ответ 1
Согласно docs, это точно так же.
Однако использование Schema также добавило бы поле _id
(пока у вас этого нет), и, по-видимому, использует еще несколько ресурсов для отслеживания поддоменов.
Синтаксис альтернативного объявления
Новое в v3 Если вам не нужен доступ к экземпляру схемы субдоку, вы также можете объявить субдоки, просто передав объектный литерал [...]
Ответ 2
Если у вас есть схемы, которые повторно используются в разных частях вашей модели, тогда было бы полезно определить отдельные схемы для дочерних документов, чтобы вам не приходилось дублировать себя.
Ответ 3
Я думаю, что это обрабатывается в другом месте несколькими сообщениями на SO.
Всего несколько:
Большой ключ заключается в том, что здесь нет единого ответа, только набор довольно сложных компромиссов.
Ответ 4
Вы должны использовать встроенные документы, если это статические документы или не более нескольких сотен из-за воздействия производительности. Некоторое время назад я рассказывал об этой проблеме. Недавно Ася Камский, которая работает архитектором решений для MongoDB, написала статью о "использовании поддокументов".
Я надеюсь, что это поможет тем, кто ищет решения или наилучшую практику.
Оригинальная публикация на http://askasya.com/post/largeembeddedarrays.
Вы можете достигнуть ее профиля stackoverflow на https://stackoverflow.com/users/431012/asya-kamsky
Прежде всего, мы должны рассмотреть, почему мы хотели бы сделать такое вещь. Обычно я бы посоветовал людям вставлять вещи, которые они всегда хотят вернуться, когда они извлекают этот документ. Флип сторона этого заключается в том, что вы не хотите вставлять вещи в документ что вы не хотите возвращаться с ним.
Если вы включите активность, которую я выполняю в документе, она отлично подойдет во-первых, потому что вся моя деятельность прямо там и с одним чтением вы можете вернуть все, что вы могли бы мне показать: "вы недавно нажал на это, и вот ваши последние два комментария", но что происходит после шести месяцев, и я не забочусь о том, что я сделал долгое время назад, и вы не хотите показывать их мне, если я специально не перейду к искать какую-то старую активность?
Во-первых, вы в конечном итоге вернете больший и больший документ и заботу о меньшей и меньшей его части. Но вы можете использовать проекцию для вернуть только часть массива, реальная боль заключается в том, что документ на диск станет больше, и он все равно будет прочитан, даже если вы только возвращая часть его конечному пользователю, но поскольку моя деятельность не останавливаясь, пока я активен, документ будет продолжаться растет и растет.
Самая очевидная проблема с этим - в конечном итоге вы попадете в 16MB лимит документа, но это вовсе не то, что вы должны беспокоить около. Документ, который будет постоянно расти, будет все больше и больше стоить каждый раз, когда он должен переместиться на диск, и даже если вы шаги по смягчению последствий фрагментации, ваши записи будут в целом, должны быть излишне длинными, влияя на общую производительность вашего всего приложения.
Есть еще одна вещь, которую вы можете сделать, которая полностью уничтожит ваши производительности приложения и чтобы индексировать это постоянно увеличивающееся массив. Это означает, что каждый раз документ с этот массив перемещается, количество записей индекса, которое должно быть обновляется прямо пропорционально числу индексированных значений в этот документ, и чем больше массив, тем больше это число будет быть.
Я не хочу, чтобы это пугало вас от использования массивов, когда они хороши подходят для модели данных - они являются мощной особенностью документа модель данных базы данных, но, как и все мощные инструменты, ее необходимо использовать при правильных обстоятельствах, и его следует использовать с осторожностью.
Ответ 5
В принципе создайте переменную nestedDov
и поместите ее здесь name: [nestedDov]
Простая версия:
var nestedDoc = new Schema({
name: String
});
var mainDoc = new Schema({
names: [nestedDoc]
});
Пример JSON
{
"_id" : ObjectId("57c88bf5818e70007dc72e85"),
"name" : "Corinthia Hotel Budapest",
"stars" : 5,
"description" : "The 5-star Corinthia Hotel Budapest on the Grand Boulevard offers free access to its Royal Spa",
"photos" : [
"/photos/hotel/corinthiahotelbudapest/1.jpg",
"/photos/hotel/corinthiahotelbudapest/2.jpg"
],
"currency" : "HUF",
"rooms" : [
{
"type" : "Superior Double or Twin Room",
"number" : 20,
"description" : "These are some great rooms",
"photos" : [
"/photos/room/corinthiahotelbudapest/2.jpg",
"/photos/room/corinthiahotelbudapest/5.jpg"
],
"price" : 73000
},
{
"type" : "Deluxe Double Room",
"number" : 50,
"description" : "These are amazing rooms",
"photos" : [
"/photos/room/corinthiahotelbudapest/4.jpg",
"/photos/room/corinthiahotelbudapest/6.jpg"
],
"price" : 92000
},
{
"type" : "Executive Double Room",
"number" : 25,
"description" : "These are amazing rooms",
"photos" : [
"/photos/room/corinthiahotelbudapest/4.jpg",
"/photos/room/corinthiahotelbudapest/6.jpg"
],
"price" : 112000
}
],
"reviews" : [
{
"name" : "Tamas",
"id" : "/user/tamas.json",
"review" : "Great hotel",
"rating" : 4
}
],
"services" : [
"Room service",
"Airport shuttle (surcharge)",
"24-hour front desk",
"Currency exchange",
"Tour desk"
]
}
Пример:
![введите описание изображения здесь]()