Поддокументы 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"
    ]
}

Пример:

введите описание изображения здесь