csatlakozások használata a MongoDB NoSQL adatbázisokban

$lookUp használata a NoSQL-lel

köszönet Julian Motznak, hogy kedvesen segített a cikk szakértői értékelésében.

az egyik legnagyobb különbség az SQL és a NoSQL adatbázisok között a JOIN. A relációs adatbázisokban az SQL JOIN záradék lehetővé teszi két vagy több tábla sorainak kombinálását egy közös mező használatával. Ha például books és publishers táblákkal rendelkezik, akkor SQL parancsokat írhat, például:

SELECT book.title, publisher.nameFROM bookLEFT JOIN book.publisher_id ON publisher.id;

más szavakkal, a book táblának van egy publisher_id mezője, amely a id mezőre hivatkozik a publisher táblázatban.

ez praktikus, mivel egyetlen kiadó több ezer könyvet kínálhat. Ha valaha is frissítenünk kell egy kiadó adatait, egyetlen rekordot megváltoztathatunk. Az adatok redundanciája minimálisra csökken, mivel nem kell minden könyvnél megismételnünk a kiadói információkat. A technikát normalizációnak nevezik.

az SQL adatbázisok számos normalizálási és kényszer funkciót kínálnak a kapcsolatok fenntartásának biztosítására.

NoSQL = = nincs csatlakozás?

nem mindig …

a Dokumentumorientált adatbázisok, mint például a MongoDB, a denormalizált adatok tárolására szolgálnak. Ideális esetben nincs kapcsolat a gyűjtemények között. Ha ugyanazokra az adatokra van szükség két vagy több dokumentumban, meg kell ismételni.

ez frusztráló lehet, mivel kevés olyan helyzet van, ahol soha nincs szükség relációs adatokra. Szerencsére a MongoDB 3.2 bevezet egy új $lookup operátort, amely két vagy több gyűjteményen képes bal-külső ILLESZTÉSSZERŰ műveletet végrehajtani. De van egy fogás …

MongoDB Összesítés

$lookup csak összesítési műveletekben engedélyezett. Gondoljon ezekre úgy, mint operátorok csővezetékére, amelyek lekérdezik, szűrik és csoportosítják az eredményt. Az egyik operátor kimenetét a következő bemeneteként használják.

az összesítést nehezebb megérteni, mint az egyszerűbb find lekérdezéseket, és általában lassabban futnak. Ezek azonban erőteljesek és felbecsülhetetlen lehetőségek a komplex Keresési műveletekhez.

az összesítést legjobban egy példával magyarázhatjuk. Tegyük fel, hogy létrehozunk egy közösségi média platformot egy user gyűjteménygel. Minden felhasználó adatait külön dokumentumokban tárolja. Például:

{ "_id": ObjectID("45b83bda421238c76f5c1969"), "name": "User One", "email: "[email protected]", "country": "UK", "dob": ISODate("1999-09-13T00:00:00.000Z")}

annyi mezőt adhatunk hozzá, amennyire szükséges, de minden MongoDB dokumentumhoz _id mező szükséges, amelynek egyedi értéke van. A _id hasonló egy SQL elsődleges kulcshoz, és szükség esetén automatikusan beillesztésre kerül.

közösségi hálózatunknak most egy post gyűjteményre van szüksége, amely számos, a felhasználóktól származó, áttekinthető frissítést tárol. A dokumentumok user_id mezőben tárolják a szöveget, a dátumot, a minősítést és a hivatkozást arra a felhasználóra, aki írta:

{ "_id": ObjectID("17c9812acff9ac0bba018cc1"), "user_id": ObjectID("45b83bda421238c76f5c1969"), "date: ISODate("2016-09-05T03:05:00.123Z"), "text": "My life story so far", "rating": "important"}

most meg akarjuk mutatni az utolsó húsz hozzászólást az összes felhasználó “fontos” minősítésével fordított időrendi sorrendben. Minden visszaküldött dokumentumnak tartalmaznia kell a szöveget, a bejegyzés idejét, valamint a társított felhasználó nevét és országát.

a MongoDB aggregált lekérdezést egy sor csővezeték-operátor adja át, amelyek az egyes műveleteket sorrendben határozzák meg. Először ki kell vonnunk az összes dokumentumot a post gyűjteményből, amelyek megfelelő minősítéssel rendelkeznek a $match szűrő segítségével:

{ "$match": { "rating": "important" } }

most a $sort operátor segítségével fordított dátum sorrendbe kell rendeznünk az egyező elemeket:

{ "$sort": { "date": -1 } }

mivel csak húsz hozzászólásra van szükségünk, alkalmazhatunk egy $limit stádiumot, így a MongoDB-nek csak a kívánt adatokat kell feldolgoznia:

{ "$limit": 20 }

most a user gyűjteményből származó adatokat az új $lookup operátor segítségével csatlakoztathatjuk. Négy paraméterrel rendelkező objektumot igényel:

  • localField: a beviteli dokumentum keresési mezője
  • from: a gyűjtemény csatlakozni
  • foreignField: a from gyűjteményben keresendő mező
  • as: a kimeneti mező neve.

üzemeltetőnk ezért:

{ "$lookup": { "localField": "user_id", "from": "user", "foreignField": "_id", "as": "userinfo"} }

ez egy új mezőt hoz létre a kimenetünkben userinfo néven. Tartalmaz egy tömböt, ahol minden érték megegyezik a user dokumentummal:

"userinfo": 

a post.user_id és user._id között egy-egy kapcsolat van, mivel egy bejegyzésnek csak egy szerzője lehet. Ezért a userinfo tömbünk csak egy elemet tartalmaz. Használhatjuk a $unwind operátort, hogy egy aldokumentumba dekonstruáljuk:

{ "$unwind": "$userinfo" }

a kimenet most egy praktikusabb formátumra konvertálódik, amely további operátorokat alkalmazhat:

"userinfo": { "name": "User One", "email: "[email protected]", …}

végül visszaadhatjuk a szöveget, a bejegyzés idejét, a felhasználó nevét és az országot a folyamat $project szakaszában:

{ "$project": { "text": 1, "date": 1, "userinfo.name": 1, "userinfo.country": 1} }

mindent összerakva

végső összesített lekérdezésünk megegyezik a bejegyzésekkel, rendezi a sorrendet, korlátozza a legutóbbi húsz elemet, összekapcsolja a felhasználói adatokat, ellapítja a felhasználói tömböt, és csak a szükséges mezőket adja vissza. A teljes parancs:

db.post.aggregate();

az eredmény legfeljebb húsz dokumentum gyűjteménye. Például:

nagyszerű! Végre át tudok váltani a NoSQL-re!

a MongoDB $lookup hasznos és hatékony, de még ez az alapvető példa is komplex aggregált lekérdezést igényel. Ez nem helyettesíti az SQL-ben kínált erősebb csatlakozási záradékot. A MongoDB sem kínál korlátokat; ha egy user dokumentumot törölnek, az orphan post dokumentumok megmaradnak.

ideális esetben a $lookup operátort ritkán kell megkövetelni. Ha nagyon szüksége van rá, akkor valószínűleg rossz adattárat használ…

ha rendelkezik relációs adatokkal, használjon relációs (SQL) adatbázist!

ennek ellenére a $lookup örvendetes kiegészítés a MongoDB 3.2-hez. Meg tudja oldani néhány frusztráló problémát, ha kis mennyiségű relációs adatot használ egy NoSQL adatbázisban.

You might also like

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.