Піддокументи мангусти проти вкладеної схеми


122

Мені цікаво плюси та мінуси використання піддокументів та глибшого шару в моїй головній схемі:

var subDoc = new Schema({
  name: String
});

var mainDoc = new Schema({
  names: [subDoc]
});

або

var mainDoc = new Schema({
  names: [{
    name: String
 }]
});

В даний час я використовую піддокументи скрізь, але мені цікаво в першу чергу питання щодо продуктивності чи запитів, з якими я можу зіткнутися.


Я намагався набрати відповідь на це, але я не міг знайти як. Але погляньте тут: mongoosejs.com/docs/subdocs.html
gustavohenke

Ось хороший відповідь про міркування MongoDB , щоб запитати себе при створенні схеми бази даних: stackoverflow.com/questions/5373198 / ...
anthonylawson

Ви мали на увазі, що потрібно також описати _idполе? Я маю на увазі, це не якесь автоматичне, якщо воно включене?
Vadorequest

хтось знає, чи _idунікальна область піддокументів? (створено за допомогою другого способу у питанні щодо ОП)
Сайтама

Відповіді:


72

Згідно з документами , це точно так само. Однак використання схеми також додасть _idполе (доки ви не маєте цього відключеного), і, імовірно, використовує ще кілька ресурсів для відстеження субдокументів.

Альтернативний синтаксис оголошення

Нове в v3 Якщо вам не потрібен доступ до екземпляра схеми піддокумента, ви також можете оголосити піддокументи, просто передавши об'єкт буквально [...]


1
Але я спробував це. Чому дані піддокументів не зберігаються в окремому зборі. Він завжди зберігається всередині колекції mainDoc.
Фізер Хан

17
ось як працюють піддокументи. вони вбудовуються всередину документа. перш ніж грати з мангустом, переконайтеся, що ви розумієте основний MongoDB.
AndyL

1
Що стосується додавання схеми _id, це має сенс, але я створив схему з масивом піддокументів та масивом об'єктних літералів, а _id додано до обох. Чи змінилася поведінка?
Дрю Гудвін

@DrewGoodwin здається, що це було деякий час: stackoverflow.com/questions/17254008/…
cheesemacfly

37

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


4
Це чудова відповідь. Іноді я використовую піддокументи в більш ніж одній моделі, або у мене є два поля в моделі, яку потрібно розрізнити, але все ж мають однакову структуру субдокументів.
Мартін Галлен

2
Ви також повинні врахувати переваги / недоліки збереження зайвої інформації.
Сем Влобергс

25

Ви повинні використовувати вбудовані документи, якщо це статичні документи або їх не більше кількох сотень через вплив на продуктивність. Я певний час займався цим питанням. Нещодавно Ася Камська, яка працює архітектором рішень для MongoDB, написала статтю про "використання піддокументів".

Я сподіваюся, що це допоможе тому, хто шукає рішення чи найкращу практику.

Оригінальна публікація на http://askasya.com/post/largeembeddedarrays . Ви можете отримати її профіль stackoverflow на https://stackoverflow.com/users/431012/asya-kamsky

Перш за все, ми повинні врахувати, чому ми хотіли б зробити таке. Зазвичай я радив би людям вставляти речі, які вони завжди хочуть повернути, коли вони отримують цей документ. Зворотний бік цього полягає в тому, що ви не хочете вставляти речі в документ, які ви не хочете повертати назад.

Якщо ви вбудовуєте активність, яку я виконую в документ, спочатку вона буде чудово працювати, тому що вся моя активність знаходиться саме там, і за допомогою одного читання ви зможете отримати все, що ви можете мені показати: "Ви нещодавно натиснули на це і тут ваші останні два коментарі ", але що відбувається через півроку, і мені все одно, що я робив давно, і ти не хочеш їх показувати мені, якщо я спеціально не шукаю старого заняття?

По-перше, ви в кінцевому підсумку повернете все більший і більший документ і піклуєтеся про меншу і меншу його частину. Але ви можете використовувати проекцію лише для повернення частини масиву, справжня біль полягає в тому, що документ на диску стане більшим, і він все ще буде прочитаний, навіть якщо ви збираєтеся лише повернути частину його кінцевому користувачеві, але оскільки моя діяльність не припинятиметься, поки я активна, документ продовжуватиме зростати та зростати.

Найбільш очевидна проблема з цим - це врешті-решт ви досягнете ліміту документа в 16МБ, але це зовсім не те, про що ви повинні турбуватися. Документ, який постійно зростає, матиме все більшу і більшу вартість щоразу, коли йому доведеться переїхати на диск, і навіть якщо ви вживатимете заходи щодо пом’якшення наслідків фрагментації, ваші записи будуть загалом непотрібними, впливаючи на загальну ефективність всієї вашої програми.

Є ще одне, що ви можете зробити, що повністю знищить продуктивність вашої програми, і це проіндексувати цей постійно зростаючий масив. Це означає, що щоразу, коли документ із цим масивом переміщується, кількість записів індексу, які потрібно оновити, прямо пропорційна кількості індексованих значень у цьому документі, і чим більший масив, тим більшим буде це число бути.

Я не хочу, щоб це лякало вас від використання масивів, коли вони добре підходять для моделі даних - вони є потужною особливістю моделі даних бази даних документів, але, як і всі потужні інструменти, її потрібно використовувати в правильних обставинах і його слід використовувати обережно.


3
Це має бути головна відповідь; це удар на гроші. Власні документи MongoDB говорять майже про те саме.
Джей Едвардс

Ця стаття про схему Bucket Pattern компліментує те, про що добре говорить Ася. mongodb.com/blog/post/building-with-patterns-the-bucket-pattern Я думаю, що схема subDoc у запитанні ОП добре працюватиме із схемою Bucket.
plong0

13

В основному, створіть змінну 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"
    ]
}

Приклад:

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


1
Це взагалі не стосується питання, яке є одним із результатів.
cyberwombat

Я трохи відредагував, щоб мати більше сенсу. Що ти думаєш?
Вейн Чіу

3
Питання не в питанні, як робити вкладені схеми. Обговорення питання про те, чи є Мангуст більш ефективним із вкладеними схемами чи вбудованими піддокументами. В основному ми говоримо про еталони чи сортування чи крайові випадки, коли мангуст віддає перевагу одному перед іншим. І як згадується обрана відповідь, схоже, що це не має ніякого значення, принаймні від V3.
кібервомбат

17
Можливо, це не працює для ОП, але я вважаю це дуже корисним. Дякую.
Джин Хіггінс

Це добре, коли всі 3 схеми оголошені в одному файлі .js, як ми можемо обробити його, коли оголошено в трьох різних .js-файлах?
Сатьям

9

Я думаю, що це вирішується в іншому місці за допомогою декількох публікацій на SO.

Лише декілька:

Велике значення полягає в тому, що тут немає однозначної відповіді, а лише набір досить складних компромісів.


3
Можливо, я не правильно формулюю своє запитання - це не питання про те, як я повинен структурувати свою базу даних, а швидше про внутрішнє використання підсхеми проти просто написання масиву в більш глибокому шарі. Моя основна причина використання підсхеми полягає в тому, що я можу використовувати власні типи схем і перевірити їх - те, що не працює з вкладеними масивами (з попереднього питання, яке було у мене на SO). Наскільки я можу сказати, subdoc майже такий же, як і вкладений масив - я просто не знаю внутрішніх даних цього - якщо їх використання створювало б проблеми з продуктивністю чи подібними.
cyberwombat

0

Існує деяка різниця між двома:

  • Використання вкладеної схеми корисно для перевірки.

  • Вкладена схема може бути повторно використана в інших схемах.

  • Вкладена схема додає поле "_id" до піддокумента, якщо ви не використовували "_id: false"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.