Трябва да обмислите типа заявки, които ще трябва да изпълнявате, и колко често ще е необходим всеки тип. Когато работех върху нещо подобно, измислих шест възможни действия:
- Направете нещо с родителя
- Направете нещо с децата
- Направете нещо с предците (родители на родители, родители на родители на родители и т.н.)
- Направете нещо с потомците (деца на деца, деца на деца на деца и т.н.)
- Промяна на връзки (добавяне/преместване/изтриване на възли в йерархията)
- Промяна на основните данни в текущия възел (напр. промяна на стойността в полето „title“)
Ще искате да прецените колко важно е всяко от тях за вашето приложение.
Ако по-голямата част от работата ви включва работа със съхранени данни за дадена статия, включително нейния непосредствен родител и деца, първата идея е най-полезен. Наистина в MongoDB е доста обичайно да поставяте цялата информация, от която се нуждаете, в един и същ документ, вместо да го препращате външно, така че трябва да извлечете само едно нещо и просто да работите с тези данни. Последните четири действия в списъка обаче са по-трудни.
По-специално, ще трябва да преминете през дървото, за да извлечете предци и потомци в този случай, преминавайки през междинни документи и следвайки път, въпреки че може да се интересувате само от последния документ в пътя. Това може да е бавно за дълги йерархии. Промяната на връзките може да изисква преместване на много информация в множество документи поради всички данни, присъстващи във всеки един. Но дори промяната на едно поле като „заглавие“ може да бъде досадно, защото трябва да имате предвид факта, че това поле присъства в множество различни документи, или като основно поле, или под родителските или дъщерните полета.
По принцип, вашата първа идея работи най-добре в по-статични приложения където няма да променяте много данните след първоначалното им създаване, но трябва да ги четете редовно.
Документацията на MongoDB съдържа пет препоръчителни подхода за работа с дървовидни (йерархични) структури. Всички те имат различни предимства и недостатъци, въпреки че всички те улесняват актуализирането на основните данни в статия, като е необходимо да го направите само в един документ.
- Препоръки на родители :всеки възел съдържа препратка към своя родител.
- Предимства :
- Бързо родителско търсене (търсене по „_id“ =заглавието на вашия документ, връщане на поле „родител“)
- Бързо търсене на деца (търсене по "родител" =заглавие на вашия документ, което ще върне всички дъщерни документи)
- Актуализирането на връзките е само въпрос на промяна на полето "родител"
- Промяната на основните данни изисква промени само в един документ
- Недостатъци :
- Търсенето по предци и потомци е бавно, изисква обхождане
- Препратки към деца :всеки възел съдържа референтен масив към неговите деца
- Предимства :
- Бързо извличане на деца (връщане на масива деца)
- Бързо актуализиране на връзката (просто актуализирайте детския масив, където е необходимо)
- Недостатъци :
- Намирането на родител изисква търсене на вашия _id във всички дъщерни масиви на всички документи, докато не го намерите (тъй като родителят ще съдържа текущия възел като дъщерен)
- Търсенето на предци и потомци изисква обхождане на дървото
- Предимства :
- Масив от предци :всеки възел съдържа препратка към масив от своите предшественици &своя родител
- Предимства :
- Бързо извличане на предци (не е необходимо обхождане за намиране на конкретен)
- Лесен за търсене родител и деца, следвайки подхода „Препозовавания на родители“
- За да намерите потомци, просто потърсете предците, защото всички потомци трябва да съдържат едни и същи предци
- Недостатъци :
- Трябва да се грижите за поддържането на масива от предшественици, както и родителското поле актуализирани винаги, когато има промяна в отношенията, често в множество документи.
- Предимства :
- Материализирани пътища :всеки възел съдържа път до себе си - изисква регулярен израз
- Предимства :
- Лесно намиране на деца и потомци с помощта на регулярен израз
- Може да използва път за извличане на родител и предци
- Гъвкавост, като намиране на възли по частични пътища
- Недостатъци :
- Промените в отношенията са трудни, тъй като може да изискват промени в пътищата в множество документи
- Предимства :
- Вложени набори :Всеки възел съдържа "ляво" и "дясно" поле за помощ при намиране на поддървета
- Предимства :
- Лесно извличане на потомци по оптимален начин чрез търсене между „ляво“ и „дясно“
- Подобно на подхода „Справка за родители“, лесно е да намерите родител и деца
- Недостатъци :
- Трябва да преминете през структурата, за да намерите предци
- Промените в отношенията се представят най-лошо тук от всяка друга опция, тъй като може да се наложи всеки един документ в дървото да бъде променен, за да се гарантира, че „ляво“ и „дясно“ все още имат смисъл, след като нещо се промени в йерархията
- Предимства :
Петте подхода се обсъждат по-подробно в документацията на MongoDB .
Вашата втора идея съчетава разгледаните по-горе подходи „Препратки към родители“ и „Препратки към деца“. Този подход улеснява намирането както на дъщерните, така и на родителските елементи и улеснява актуализирането на връзки и основните данни на дадена статия (въпреки че трябва да актуализирате както родителските, така и детските полета), но все пак трябва да преминете през него за намиране на предци и потомци.
Ако се интересувате от намирането на предци и потомци (и се интересувате от това повече от възможността за лесно актуализиране на връзки), можете да помислите за добавяне на масив от предци към втората си идея, за да улесните и заявките за предци и потомци. Разбира се, актуализирането на взаимоотношенията става истинска болка, ако направите това.
Заключение:
-
В крайна сметка всичко зависи от това какви действия са най-необходими. Тъй като работите със статии, чиито основни данни (като заглавието) могат да се променят често, може да искате да избегнете първата идея, тъй като ще трябва да актуализирате не само основния документ за тази статия, но и всички дъщерни документи, както и родител.
-
Втората ви идея улеснява извличането на непосредствения родител и децата. Актуализирането на връзки също не е твърде трудно (със сигурност е по-добро от някои от другите налични опции).
-
Ако наистина искате да улесните намирането на предци и потомци за сметка на лесното актуализиране на връзките, изберете да включите масив от препратки към предци.
-
По принцип се опитайте да сведете до минимум броя на необходимите обхождания, тъй като те изискват изпълнение на някакъв вид итерация или рекурсия, за да стигнете до данните, които искате. Ако цените възможността за актуализиране на връзки, трябва също да изберете опция, която променя по-малко възли в дървото (препратки за родители, препратки за деца и втората ви идея могат да направят това).