Chcete-li vytvořit vztah v MongoDB, buď vložte dokument BSON do jiného dokumentu, nebo na něj odkazujte z jiného.
Databáze MongoDB fungují jinak než relační databáze. To platí i o vztazích.
V MongoDB můžete vytvořit vztah pomocí jedné z následujících dvou metod:
- Vložené dokumenty.
- Odkazované dokumenty.
Metoda, kterou použijete, bude záviset na datech a na tom, jak máte v úmyslu tato data dotazovat.
Vložené vztahy
S MongoDB můžete vkládat dokumenty do dokumentů. Proto může jeden dokument obsahovat své vlastní vztahy.
Ve skutečnosti jsme již vytvořili vztah pomocí této metody, když jsme poprvé vytvořili dokument.
Vztah jeden k jednomu
Vztah jeden k jednomu je kde nadřazený dokument má jednoho potomka a podřízený má jednoho rodiče.
Obchodní pravidlo může například říkat, že umělec může mít pouze jednu adresu a že adresa může patřit pouze jednomu umělci.
Následující kód vytváří vztah jedna ku jedné, který je vložený do dokumentu.
db.artists.insert( { _id : 2, artistname : "Prince", address : { street : "Audubon Road", city : "Chanhassen", state : "Minnesota", country : "United States" } } )
Výsledek:
WriteResult({ "nInserted" : 1 })
Vztah jeden k mnoha
jeden k mnoha vztah je místo, kde nadřazený dokument může mít mnoho podřízených dokumentů, ale podřízené dokumenty mohou mít pouze jeden nadřazený dokument.
Jiné obchodní pravidlo by tedy mohlo říkat, že jeden interpret může mít mnoho alb, ale album může patřit pouze jednomu interpretovi.
Spuštěním následujícího kódu vytvoříte vztah jedna k mnoha:
db.artists.insert( { _id : 3, artistname : "Moby", albums : [ { album : "Play", year : 1999, genre : "Electronica" }, { album : "Long Ambients 1: Calm. Sleep.", year : 2016, genre : "Ambient" } ] } )
Výsledek:
WriteResult({ "nInserted" : 1 })
Vztahy odkazované na dokument
K vytvoření vztahu můžete použít odkaz na dokument. Namísto vkládání podřízeného dokumentu do nadřazeného dokumentu (jako jsme to udělali výše) rozdělíte podřízený dokument do jeho vlastního samostatného dokumentu.
Takže bychom mohli udělat toto:
Nadřazený dokument
db.artists.insert( { _id : 4, artistname : "Rush" } )
Podřízené dokumenty
Vložíme 3 podřízené dokumenty — jeden pro každého člena kapely:
db.musicians.insert( { _id : 9, name : "Geddy Lee", instrument : [ "Bass", "Vocals", "Keyboards" ], artist_id : 4 } )
db.musicians.insert( { _id : 10, name : "Alex Lifeson", instrument : [ "Guitar", "Backing Vocals" ], artist_id : 4 } )
db.musicians.insert( { _id : 11, name : "Neil Peart", instrument : "Drums", artist_id : 4 } )
Dotaz na vztah
Po vložení dvou výše uvedených dokumentů můžete použít $lookup
k provedení levého vnějšího spojení na dvou kolekcích.
To ve spojení s aggregate()
metoda a $match
pro specifikaci konkrétního umělce, o kterého máte zájem, vrátí rodičovské a podřízené dokumenty v jednom.
db.artists.aggregate([ { $lookup: { from: "musicians", localField: "_id", foreignField: "artist_id", as: "band_members" } }, { $match : { artistname : "Rush" } } ]).pretty()
Výsledek:
{ "_id" : 4, "artistname" : "Rush", "band_members" : [ { "_id" : 9, "name" : "Geddy Lee", "instrument" : [ "Bass", "Vocals", "Keyboards" ], "artist_id" : 4 }, { "_id" : 10, "name" : "Alex Lifeson", "instrument" : [ "Guitar", "Backing Vocals" ], "artist_id" : 4 }, { "_id" : 11, "name" : "Neil Peart", "instrument" : "Drums", "artist_id" : 4 } ] }
Můžete vidět, že první dvě pole jsou ze sbírky umělců a zbytek je ze sbírky hudebníků.
Pokud se tedy dotazujete pouze na samotnou sbírku umělců:
db.artists.find( { artistname : "Rush" } )
Dostanete pouze toto:
{ "_id" : 4, "artistname" : "Rush" }
Nejsou vrácena žádná související data.
Kdy použít vložené dokumenty vs. odkazované dokumenty
Oba způsoby vytváření vztahů mají svá pro a proti. Někdy můžete použít vložené dokumenty a jindy zase dokumenty, na které se odkazuje.
Kdy použít vložené vztahy
Jednou z hlavních výhod použití metody vestavěných vztahů je výkon. Když je vztah vložen do dokumentu, dotazy poběží rychleji, než kdyby byly rozloženy do více dokumentů. MongoDB potřebuje vrátit pouze jeden dokument, spíše než spojovat více dokumentů, aby bylo možné načíst vztahy. To může poskytnout výrazné zvýšení výkonu – zejména při práci s velkým množstvím dat.
Vložené vztahy také usnadňují psaní dotazů. Namísto psaní složitých dotazů, které spojují mnoho dokumentů prostřednictvím jejich jedinečného identifikátoru, můžete vrátit všechna související data v rámci jediného dotazu.
Dalším aspektem, který je třeba mít na paměti, je, že MongoDB může zajistit atomicitu pouze na úrovni dokumentu. Aktualizace dokumentu do jednoho dokumentu jsou vždy atomické, ale ne pro více dokumentů.
Když k datům přistupuje více uživatelů, vždy existuje šance, že se dva nebo více uživatelů pokusí aktualizovat stejný dokument různými daty. V tomto případě MongoDB zajistí, že nedojde ke konfliktu a vždy se aktualizuje pouze jedna sada dat. MongoDB to nemůže zajistit ve více dokumentech.
Obecně tedy lze ve většině případů použít vložené vztahy, pokud dokument zůstane v rámci limitu velikosti (16 megabajtů v době psaní) a/nebo limitu vnoření (hloubka 100 úrovní v době psaní).
Vložené vztahy však nejsou vhodné pro všechny příležitostech. Mohou nastat situace, kdy má větší smysl vytvořit vztah odkazovaný na dokument.
Kdy použít referenční vztahy
Pro data, která je třeba opakovat v mnoha dokumentech, může být užitečné mít je v samostatném dokumentu. To může snížit chyby a pomoci udržet data konzistentní (a zároveň mít na paměti, že aktualizace více dokumentů nejsou atomické).
Pomocí výše uvedeného příkladu by jeden hudebník mohl být členem (nebo bývalým členem) mnoha kapel. Někteří mohou také produkovat alba pro jiné umělce, učit studenty, provozovat kliniky atd. Také by mohlo být uloženo mnoho dat proti každému hudebníkovi. Takže mít samostatný dokument pro každého hudebníka má v tomto případě smysl.
Pokud si také myslíte, že by vaše vložené dokumenty mohly překročit limit velikosti souboru stanovený MongoDB, budete muset některá data uložit do samostatných dokumentů.