La prima cosa che vuoi decidere è esattamente quale tipo di albero utilizzerai.
La cosa importante da considerare sono i dati e i modelli di accesso. Hai già affermato che il 90% di tutto il tuo lavoro verrà sottoposto a query e, con il suo suono (e-commerce), gli aggiornamenti verranno eseguiti solo dagli amministratori, molto probabilmente raramente.
Quindi vuoi uno schema che ti dia la possibilità di interrogare rapidamente sul bambino attraverso un percorso, ad esempio: Sport -> Basket -> Uomo, Sport -> Tennis -> Donna, e non ha davvero bisogno di scalare veramente agli aggiornamenti.
Come hai giustamente osservato MongoDB ha una buona pagina di documentazione per questo: http://docs.mongodb.org/manual/tutorial/model-tree-structures/ in cui 10gen in realtà indica modelli diversi e metodi di schema per alberi e descrive i principali alti e bassi di essi.
Quello che dovrebbe catturare l'attenzione se si sta cercando di interrogare i percorsi facilmente si materializza: http://docs.mongodb.org/manual/tutorial/model-tree-structures/#model-tree-structures-with-materialized-paths
questo è un metodo molto interessante per costruire alberi in quanto per interrogare l'esempio che hai dato sopra in "Donna" in "Tennis" si potrebbe semplicemente fare una regex prefissato (che può utilizzare l'indice: http://docs.mongodb.org/manual/reference/operator/regex/) in questo modo:
db.products.find({category: /^Sports,Tennis,Womens[,]/})
per trovare tutti i prodotti elencati sotto un certo percorso del vostro albero.
Purtroppo questo modello è davvero pessimo in fase di aggiornamento, se si sposta una categoria o si modifica il suo nome è necessario aggiornare tutti i prodotti e potrebbero esserci migliaia di prodotti in una categoria.
Un metodo migliore sarebbe quello di ospitare una cat_id
sul prodotto e quindi separare le categorie in una raccolta differenziata con lo schema:
{
_id: ObjectId(),
name: 'Women\'s',
path: 'Sports,Tennis,Womens',
normed_name: 'all_special_chars_and_spaces_and_case_senstive_letters_taken_out_like_this'
}
Così ora le vostre domande riguardano solo la raccolta categorie che dovrebbe renderli molto più piccolo e più performante. L'eccezione a questo è quando si elimina una categoria, i prodotti dovranno ancora toccare.
Così un esempio di modifica "Tennis" a "Badmin":
db.categories.update({path:/^Sports,Tennis[,]/}).forEach(function(doc){
doc.path = doc.path.replace(/,Tennis/, ",Badmin");
db.categories.save(doc);
});
Purtroppo MongoDB fornisce alcuna riflessione documento-query al momento quindi che c'è bisogno di tirare fuori lato client che è un po ' fastidioso, tuttavia, si spera, non dovrebbe comportare il rientro di troppe categorie.
E questo è fondamentalmente come funziona davvero. È un po 'difficile aggiornare, ma il potere di essere in grado di eseguire query istantaneamente su qualsiasi percorso utilizzando un indice è più adatto per il tuo scenario.
Ovviamente il vantaggio è che questo schema è compatibile con i modelli di serie annidati: http://en.wikipedia.org/wiki/Nested_set_model che ho trovato più e più volte fantastico per i siti di e-commerce, ad esempio, Tennis potrebbe essere sotto entrambi gli "Sport" e "Tempo libero" e desideri percorsi multipli a seconda della provenienza dell'utente.
Lo schema per percorsi materializzati supporta facilmente questo semplicemente aggiungendo un altro path
, che semplice.
Spero che abbia senso, piuttosto lungo.
I percorsi materializzati sono efficaci durante l'interrogazione mentre l'aggiornamento è più lento – Sammaye
il collegamento mongodb docs elenca cinque approcci, non uno e penso che il terzo aspetto sia perfettamente adeguato per il tuo caso d'uso. –