Programování

Big data analytics with Neo4j and Java, Part 1

Relační databáze dominují ve správě dat po celá desetiletí, ale nedávno ztratily půdu pod nohama alternativami. I když úložiště dat NoSQL nejsou správná pro každý případ použití, jsou obecně lepší velká data, což je zkratka pro systémy, které zpracovávají obrovské objemy dat. Pro velká data se používají čtyři typy úložiště dat:

  • Úložiště klíč / hodnota, například Memcached a Redis
  • Dokumentově orientované databáze jako MongoDB, CouchDB a DynamoDB
  • Sloupcově orientovaná datová úložiště, jako jsou Cassandra a HBase
  • Grafické databáze jako Neo4j a OrientDB

Tento výukový program představuje Neo4j, což je databáze grafů používaná pro interakci s vysoce související data. Zatímco relační databáze jsou dobré při správě vztahů mezi data, databáze grafů jsou lepší při správě n-tý stupně vztahů. Jako příklad si vezměte sociální síť, kde chcete analyzovat vzorce zahrnující přátele, přátele přátel atd. Databáze grafů by usnadnila odpověď na otázku typu: „Vzhledem k pěti stupňům oddělení, jaké jsou pět filmů populárních v mé sociální síti, které jsem ještě neviděl?“ Takové otázky jsou běžné pro doporučovací software a databáze grafů jsou ideální pro jejich řešení. Databáze grafů navíc dobře reprezentují hierarchická data, například řízení přístupu, katalogy produktů, databáze filmů nebo dokonce topologie sítí a organizační schémata. Pokud máte objekty s více vztahy, rychle zjistíte, že databáze grafů nabízejí elegantní objektově orientované paradigma pro správu těchto objektů.

Případ databází grafů

Jak název napovídá, databáze grafů dobře reprezentují grafy dat. To je užitečné zejména pro sociální software, kde pokaždé, když se s někým spojíte, je mezi vámi definován vztah. Pravděpodobně při svém posledním hledání zaměstnání jste si vybrali několik společností, které vás zajímaly, a poté jste ve svých sociálních sítích hledali spojení. I když možná neznáte nikoho, kdo pracuje pro některou z těchto společností, pravděpodobně to někdo ve vaší sociální síti ví. Řešení takového problému je snadné při jednom nebo dvou stupních oddělení (váš přítel nebo přítel přítele), ale co se stane, když začnete rozšiřovat vyhledávání po celé síti?

Ve své knize Neo4j In Action zkoumají Aleksa Vukotic a Nicki Watt rozdíly mezi relačními databázemi a databázemi grafů pro řešení problémů sociálních sítí. Pro několik dalších příkladů čerpám z jejich práce, abych vám ukázal, proč se databáze grafů stávají stále oblíbenější alternativou relačních databází.

Modelování složitých vztahů: Neo4j vs MySQL

Z pohledu informatiky, když přemýšlíme o modelování vztahů mezi uživateli v sociální síti, můžeme nakreslit graf jako ten na obrázku 1.

Steven Haines

Uživatel má IS_FRIEND_OF vztahy s ostatními uživateli a tito uživatelé mají IS_FRIEND_OF vztahy s ostatními uživateli atd. Obrázek 2 ukazuje, jak bychom to reprezentovali v relační databázi.

Steven Haines

The UŽIVATEL tabulka má vztah jedna k mnoha s USER_FRIEND tabulka, která modeluje vztah „přátel“ mezi dvěma uživateli. Nyní, když jsme modelovali vztahy, jak bychom dotazovali naše data? Vukotic a Watt měřili výkon dotazu pro počítání počtu odlišných přátel, kteří šli do hloubky pěti úrovní (přátelé přátel přátel přátel přátel přátel). V relační databázi by dotazy vypadaly takto:

 # Hloubka 1 vyberte počet (odlišný uf. *) Od user_friend uf kde uf.user_1 =? # Hloubka 2 vyberte počet (odlišný uf2. *) Od user_friend uf1 vnitřní spojení user_friend uf2 na uf1.user_1 = uf2.user_2 kde uf1.user_1 =? # Hloubka 3 vyberte počet (odlišný uf3. *) Od t_user_friend uf1 vnitřní spojení t_user_friend uf2 na uf1.user_1 = uf2.user_2 vnitřní spojení t_user_friend uf3 na uf2.user_1 = uf3.user_2 kde uf1.user_1 =? # A tak dále... 

Zajímavé na těchto dotazech je to, že pokaždé, když vyjdeme o jednu úroveň více, musíme se připojit USER_FRIEND stůl sám se sebou. Tabulka 1 ukazuje, co výzkumníci Vukotic a Watt našli, když vložili 1 000 uživatelů s přibližně 50 vztahy každý (50 000 vztahů) a spustili dotazy.

Tabulka 1. Doba odezvy na dotaz MySQL pro různé hloubky vztahů

DepthExecution time (seconds) Count result

20.028~900
30.213~999
410.273~999
592.613~999

MySQL dělá skvělou práci při spojování dat až o tři úrovně dál, ale výkon se poté rychle sníží. Důvodem je, že pokaždé, když USER_FRIEND tabulka je spojena sama se sebou, MySQL musí spočítat kartézský součin tabulky, přestože většina dat bude vyhozena. Například při provádění tohoto spojení pětkrát má kartézský součin 50 000 ^ 5 řádků nebo 102,4 * 10 ^ 21 řádků. To je plýtvání, když nás zajímá pouze 1 000 z nich!

Dále se Vukotic a Watt pokusili provést stejný typ dotazů proti Neo4j. Tyto zcela odlišné výsledky jsou uvedeny v tabulce 2.

Tabulka 2. Doba odezvy Neo4j pro různé hloubky vztahů

DepthExecution time (seconds) Count result

20.04~900
30.06~999
40.07~999
50.07~999

Stánek s jídlem z těchto srovnání provedení je ne že Neo4j je lepší než MySQL. Spíše při procházení těmito typy vztahů závisí výkon Neo4j na počtu načtených záznamů, zatímco výkon MySQL závisí na počtu záznamů v USER_FRIEND stůl. Jak se tedy zvyšuje počet vztahů, doba odezvy pro dotazy MySQL se rovněž zvýší, zatímco doba odezvy pro dotazy Neo4j zůstane stejná. Důvodem je, že doba odezvy Neo4j závisí na počtu vztahů pro konkrétní dotaz, a nikoli na celkovém počtu vztahů.

Škálování Neo4j pro velká data

Vukotic a Watt rozšířili tento myšlenkový projekt o krok dále a vytvořili milion uživatelů s 50 miliony vztahů mezi nimi. Tabulka 3 ukazuje výsledky pro daný soubor dat.

Tabulka 3. Doba odezvy Neo4j pro 50 milionů vztahů

DepthExecution time (seconds) Count result

20.01~2,500
30.168~110,000
41.359~600,000
52.132~800,000

Netřeba dodávat, že vděčím Aleksi Vukotic a Nicki Watt a velmi doporučuji zkontrolovat jejich práci. Všechny testy v této části jsem vytáhl z první kapitoly jejich knihy, Neo4j v akci.

Začínáme s Neo4j

Viděli jste, že Neo4j je schopen velmi rychle spouštět obrovské množství vysoce souvisejících dat a není pochyb o tom, že je pro některé druhy problémů vhodnější než MySQL (nebo jakákoli relační databáze). Pokud chcete pochopit více o tom, jak Neo4j funguje, nejjednodušší je komunikovat s ním prostřednictvím webové konzoly.

Začněte stažením Neo4j. V tomto článku budete potřebovat edici Community, která je od tohoto psaní ve verzi 3.2.3.

  • Na počítači Mac stáhněte soubor DMG a nainstalujte jej stejně jako jakoukoli jinou aplikaci.
  • Ve Windows si buď stáhněte EXE a projděte si průvodce instalací, nebo si stáhněte soubor ZIP a dekomprimujte jej na pevný disk.
  • V systému Linux si stáhněte soubor TAR a dekomprimujte jej na pevný disk.
  • Případně použijte image Dockeru v jakémkoli operačním systému.

Po instalaci Neo4j jej spusťte a otevřete okno prohlížeče na následující adrese URL:

//127.0.0.1:7474/browser/

Přihlaste se pomocí výchozího uživatelského jména neo4j a výchozí heslo pro neo4j. Měla by se zobrazit obrazovka podobná obrázku 3.

Steven Haines

Uzly a vztahy v Neo4j

Neo4j je navržen kolem konceptu uzlů a vztahů:

  • A uzel představuje věc, jako je uživatel, film nebo kniha.
  • Uzel obsahuje sadu páry klíč / hodnota, například jméno, titul nebo vydavatel.
  • Uzel označení definuje, o jaký typ věci jde - opět uživatel, film nebo kniha.
  • Vztahy definovat asociace mezi uzly a jsou konkrétních typů.

Jako příklad bychom mohli definovat uzly znaků, jako jsou Iron Man a Captain America; definovat uzel filmu s názvem „Avengers“; a poté definujte APPEARS_IN vztah mezi Iron Manem a Avengers a Captain America a Avengers. To vše je znázorněno na obrázku 4.

Steven Haines

Obrázek 4 ukazuje tři uzly (dva uzly znaků a jeden uzel filmu) a dva vztahy (oba typu APPEARS_IN).

Modelování a dotazování uzlů a vztahů

Podobně jako relační databáze používá ke komunikaci s daty Structured Query Language (SQL), Neo4j používá Cypher Query Language k interakci s uzly a vztahy.

Pojďme pomocí Cypheru vytvořit jednoduchou reprezentaci rodiny. V horní části webového rozhraní vyhledejte znak dolaru. To označuje pole, které vám umožňuje provádět dotazy Cypher přímo proti Neo4j. Do tohoto pole zadejte následující dotaz Cypher (jako příklad používám svou rodinu, ale pokud chcete, můžete změnit podrobnosti a modelovat svou vlastní rodinu):

VYTVOŘIT (osoba: Osoba {jméno: "Steven", věk: 45}) RETURN osoba

Výsledek je znázorněn na obrázku 5.

Steven Haines

Na obrázku 5 můžete vidět nový uzel se štítkem Osoba a jménem Steven. Pokud umístíte ukazatel myši na uzel ve webové konzole, uvidíte jeho vlastnosti v dolní části. V tomto případě jsou vlastnosti ID: 19, jméno: Steven a věk: 45. Nyní pojďme rozdělit dotaz Cypher:

  • VYTVOŘIT: The VYTVOŘIT klíčové slovo se používá k vytvoření uzlů a vztahů. V tomto případě mu předáme jediný argument, kterým je a Osoba uzavřeno v závorkách, takže to má za cíl vytvořit jeden uzel.
  • (osoba: Osoba {...}): Malá písmena “osoba„je název proměnné, jehož prostřednictvím můžeme přistupovat k vytvářené osobě, zatímco kapitál“Osoba„je štítek. Upozorňujeme, že dvojtečka odděluje název proměnné od štítku.
  • {name: "Steven, věk: 45}: Toto jsou vlastnosti klíč / hodnota, které definujeme pro uzel, který vytváříme. Neo4j nevyžaduje, abyste před vytvořením uzlů definovali schéma a každý uzel může mít jedinečnou sadu prvků. (Většinu času definujete uzly se stejným štítkem, aby měly stejné vlastnosti, ale není to nutné.)
  • NÁVRATNÁ osoba: Po vytvoření uzlu požádáme Neo4j, aby nám jej vrátil zpět. To je důvod, proč jsme viděli, že se uzel objeví v uživatelském rozhraní.

The VYTVOŘIT příkaz (který nerozlišuje velká a malá písmena) se používá k vytváření uzlů a lze jej číst takto: vytvořit nový uzel se štítkem Osoba, který obsahuje vlastnosti jména a věku; přiřadit ji k proměnné osobě a vrátit ji zpět volajícímu.

Dotazování pomocí Cypher Query Language

Dále chceme zkusit nějaké dotazování s Cypherem. Nejprve budeme muset vytvořit několik dalších lidí, abychom mohli definovat vztahy mezi nimi.

 CREATE (osoba: Osoba {jméno: "Michael", věk: 16}) RETURN osoba CREATE (osoba: Osoba {jméno: "Rebecca", věk: 7}) RETURN osoba CREATE (osoba: Osoba {jméno: "Linda"}) ) NÁVRATNÁ osoba 

Jakmile vytvoříte své čtyři lidi, můžete buď kliknout na ikonu Osoba tlačítko pod Štítky uzlů (viditelné, pokud kliknete na ikonu databáze v levém horním rohu webové stránky) nebo provedete následující dotaz Cypher:

MATCH (person: Person) RETURN person

Cypher používá ZÁPAS klíčové slovo pro vyhledání věcí v Neo4j. V tomto příkladu žádáme Cypher, aby odpovídal všem uzlům, které mají štítek Person, přiřaďte tyto uzly k osoba proměnná a vrátí hodnotu, která je přidružena k této proměnné. Ve výsledku byste měli vidět čtyři uzly, které jste vytvořili. Pokud umístíte ukazatel myši na každý uzel ve webové konzole, uvidíte vlastnosti každého člověka. (Možná si všimnete, že jsem vyloučil věk mé manželky z jejího uzlu, což dokazuje, že vlastnosti nemusí být shodné napříč uzly, dokonce ani se stejným štítkem. Také nejsem pošetilý, abych zveřejnil věk mé manželky.)

Můžeme to rozšířit ZÁPAS příklad trochu dále přidáním podmínek k uzlům, které chceme vrátit. Například pokud bychom chtěli pouze uzel „Steven“, mohli bychom jej načíst pomocí shody na vlastnosti name:

ZÁPAS (osoba: Osoba {jméno: "Steven"}) NÁVRATNÁ osoba

Nebo kdybychom chtěli vrátit všechny děti, mohli bychom požádat všechny lidi ve věku do 18 let:

MATCH (person: Person) WHERE person.age <18 RETURN person

V tomto příkladu jsme přidali KDE klauzule dotazu pro zúžení našich výsledků. KDE funguje velmi podobně jako jeho ekvivalent SQL: MATCH (person: Person) najde všechny uzly se štítkem Osoba a poté KDE klauzule filtruje hodnoty z množiny výsledků.

Směr modelování ve vztazích

Máme čtyři uzly, takže vytvořme nějaké vztahy. Nejprve vytvořme IS_MARRIED_TO vztah mezi Stevenem a Lindou:

ZÁPAS (steven: Osoba {jméno: "Steven"}), (linda: Osoba {jméno: "Linda"}) CREATE (steven) - [: IS_MARRIED_TO] -> (linda) vrátit steven, linda

V tomto příkladu spojíme dva Person uzly označené Steven a Linda a vytvoříme vztah typu IS_MARRIED_TO od Stevena po Lindu. Formát pro vytvoření vztahu je následující:

(node1) - [relationshipVariable: RELATIONSHIP_TYPE -> (node2)