Devi considerare il tipo di query che dovrai eseguire e la frequenza con cui ogni tipo sarà necessario. Quando stavo lavorando a qualcosa di simile, ho escogitato sei possibili azioni:
- Fai qualcosa con il genitore
- Fai qualcosa con i bambini
- Fai qualcosa con gli antenati (genitori di genitori, genitori di genitori di genitori, ecc.)
- Fai qualcosa con i discendenti (figli di bambini, figli di bambini, ecc.)
- Cambia le relazioni (aggiungi/sposta/elimina nodi nella gerarchia)
- Modifica i dati principali nel nodo corrente (es. modificando il valore nel campo "titolo")
Ti consigliamo di stimare quanto sia importante ciascuno di questi per la tua applicazione.
Se la maggior parte del tuo lavoro prevede l'utilizzo dei dati archiviati per un determinato articolo, inclusi il genitore e i figli immediati, la prima idea è molto utile. In effetti, in MongoDB, è abbastanza comune inserire tutte le informazioni di cui hai bisogno nello stesso documento piuttosto che fare riferimento ad esso esternamente in modo che sia necessario recuperare solo una cosa e lavorare con quei dati. Le ultime quattro azioni nell'elenco sono però più complicate.
In particolare, dovrai attraversare l'albero per recuperare antenati e discendenti in questo caso, spostandoti attraverso documenti intermedi e seguendo un percorso, anche se potresti interessarti solo dell'ultimo documento nel percorso. Questo può essere lento per le gerarchie lunghe. La modifica delle relazioni può richiedere lo spostamento di molte informazioni in più documenti a causa di tutti i dati presenti in ciascuno. Ma anche modificare un singolo campo come "titolo" può essere fastidioso, perché devi considerare il fatto che questo campo è presente in più documenti diversi, sia come campo principale che sotto i campi padre o figlio.
Fondamentalmente, la tua prima idea funziona meglio in più applicazioni statiche dove non cambierai molto i dati dopo averli creati inizialmente, ma dove devi leggerli regolarmente.
La documentazione di MongoDB ha cinque approcci consigliati per la gestione di strutture ad albero (gerarchiche). Tutti presentano vantaggi e svantaggi diversi, sebbene tutti semplifichino l'aggiornamento dei dati principali in un articolo, poiché è necessario farlo in un solo documento.
- Riferimenti dei genitori :ogni nodo contiene un riferimento al suo genitore.
- Vantaggi :
- Ricerca rapida dei genitori (ricerca per "_id" =il titolo del tuo documento, restituisci il campo "genitore")
- Ricerca rapida dei bambini (ricerca per "genitore" =titolo del tuo documento, che restituirà tutti i documenti figlio)
- L'aggiornamento delle relazioni è solo questione di cambiare il campo "genitore"
- La modifica dei dati sottostanti richiede modifiche a un solo documento
- Svantaggi :
- La ricerca per antenati e discendenti è lenta e richiede una traversata
- Riferimenti figlio :ogni nodo contiene un array di riferimento ai suoi figli
- Vantaggi :
- Recupero rapido dei bambini (restituisce l'array dei bambini)
- Aggiornamento rapido delle relazioni (aggiorna semplicemente l'array dei bambini dove necessario)
- Svantaggi :
- Trovare un genitore richiede di cercare il tuo _id in tutti gli array figli di tutti i documenti finché non lo trovi (poiché il genitore conterrà il nodo corrente come figlio)
- La ricerca di antenati e discendenti richiede l'attraversamento dell'albero
- Vantaggi :
- Matrice di antenati :ogni nodo contiene un riferimento a un array dei suoi antenati e del suo genitore
- Vantaggi :
- Recupero rapido degli antenati (nessun attraversamento richiesto per trovarne uno specifico)
- Facile ricerca di genitori e figli seguendo l'approccio "Riferimenti genitori"
- Per trovare i discendenti, basta cercare gli antenati, perché tutti i discendenti devono contenere gli stessi antenati
- Svantaggi :
- È necessario preoccuparsi di mantenere aggiornati l'array di antenati e il campo padre ogni volta che si verifica un cambiamento nelle relazioni, spesso su più documenti.
- Vantaggi :
- Percorsi materializzati :ogni nodo contiene un percorso verso se stesso - richiede regex
- Vantaggi :
- Facile da trovare bambini e discendenti usando l'espressione regolare
- Può utilizzare un percorso per recuperare genitori e antenati
- Flessibilità, come trovare nodi tramite percorsi parziali
- Svantaggi :
- Le modifiche alle relazioni sono difficili in quanto potrebbero richiedere modifiche ai percorsi su più documenti
- Vantaggi :
- Set nidificati :Ogni nodo contiene un campo "sinistra" e "destra" per aiutare a trovare i sottoalberi
- Vantaggi :
- Facile da recuperare discendenti in modo ottimale cercando tra "sinistra" e "destra"
- Come l'approccio "Riferimento genitori", è facile trovare genitori e figli
- Svantaggi :
- Necessità di attraversare la struttura per trovare antenati
- Le modifiche alle relazioni sono peggiori rispetto a qualsiasi altra opzione perché potrebbe essere necessario modificare ogni singolo documento nell'albero per assicurarsi che "sinistra" e "destra" abbiano ancora senso una volta che qualcosa cambia nella gerarchia
- Vantaggi :
I cinque approcci sono discussi più dettagliatamente nella documentazione MongoDB .
La tua seconda idea combina gli approcci "Parent References" e "Child References" discussi sopra. Questo approccio semplifica la ricerca sia dei figli che del genitore e semplifica l'aggiornamento delle relazioni e dei dati principali di un articolo (sebbene sia necessario aggiornare sia il campo genitore che quello dei figli), ma è comunque necessario attraversarlo per trovare antenati e discendenti.
Se sei interessato a trovare antenati e discendenti (e ti interessa più di questo che essere in grado di aggiornare facilmente le relazioni), puoi considerare di aggiungere un array di antenati alla tua seconda idea per semplificare anche la ricerca di antenati e discendenti. Naturalmente, l'aggiornamento delle relazioni diventa un vero dolore se lo fai però.
Conclusione:
-
Alla fine tutto dipende da quali azioni sono più necessarie. Dal momento che stai lavorando con articoli, i cui dati sottostanti (come il titolo) possono cambiare frequentemente, potresti voler evitare la prima idea poiché dovresti aggiornare non solo il documento principale per quell'articolo ma tutti i documenti figlio così come il genitore.
-
La tua seconda idea semplifica il recupero del genitore e dei figli immediati. Anche l'aggiornamento delle relazioni non è troppo difficile (è sicuramente migliore di alcune delle altre opzioni disponibili).
-
Se vuoi davvero semplificare la ricerca di antenati e discendenti a scapito dell'aggiornamento delle relazioni con la stessa facilità, scegli di includere una serie di riferimenti agli antenati.
-
In generale, cerca di ridurre al minimo il numero di attraversamenti richiesti, poiché richiedono l'esecuzione di una sorta di iterazione o ricorsione per ottenere i dati desiderati. Se apprezzi la possibilità di aggiornare le relazioni, dovresti anche scegliere un'opzione che modifichi meno nodi nell'albero (riferimenti genitore, riferimenti figlio e la tua seconda idea possono farlo).