グラフデータベースに関して経験がなかったことから、グラフ指向データベースとして広く利用されている Neo4j を実際に触って得た学びを記録しておく。
Overall
今までリレーショナルデータベースに関しては触れたことがあったが、グラフデータベースに関しては全く触れたことがなく概念をつかめないでいた。 そのため、今回は実際に触れてみて理解を深めることを目指した。 今までグラフデータベースを扱う機会がなかったが、アルゴリズムの勉強をした時に Dijkstra’s algorithm などグラフに対するアルゴリズムを初めて知り、Conputer Network の授業で OSPF に Dijkstra’s algorithm が利用されていることを学んだので興味を抱いた。
CS 6250 Computer Networks Exam 1
また、現在注目されている生成 AI の観点では、手持ちの情報を用いて回答を行う RAG の利用が進んでいるが、次のステップとして Graph RAG なるものが提唱されている。 情報の関係性を踏まえることで、今まで回答できなかった質問に対しても生成 AI で回答できるようになったと報告されている。 そのため、まずはグラフとはどのようなものであるか、この機会に学ぼうと考えた。
Microsoft GraphRAG でこれまでの RAG にはできなかった質問に回答させるメモ
グラフとは
グラフに関しては、情報と情報の関係性を表現することに特化しているデータモデルである。 データの単位を表すノードとノード間の関係を示すエッジから構成され、それぞれの詳細を説明するプロパティがある。ノードとエッジに対してはラベルが付与することができ、ソーシャルネットワークであれば、ユーザーとラベルが付けられたノードはユーザーを表現する。そして、ユーザー同士の繋がりがエッジで表現される。各ユーザーのプロパティとしては、名前、年齢、性別などがある。SNS の広がりなどによって、従来のリレーショナルデータベースなどでは格納が難しいようなデータも増えたため、NoSQL の一部としてグラフ指向データベースの利用が進んだ。Neo4j に関しては、人気の高いオープンソースのグラフデータベースであることから、今回触ってみることにした。
Neo4J 構築手順
グラフデータベースを触れる環境を用意するため Neo4j の構築から開始した。 公式の docker イメージが存在しており、docker で構築することが最も簡単であったことからこちらを利用して進めた。
|
|
上記を実行後、localhost 7474 ポートで接続することで、neo4j のログイン画面に遷移する。初回はユーザー、パスワード共に neo4j でログインすることができる。
検証
データベースに接続できたので、クエリを実行し検証を行ってみる。グラフデータに対するクエリは独特の構文であり、Neo4j では Cypher で操作することになる。 また、localhost 7474 にログイン後は GUI でグラフが表示されるため、どのような関係にあるのか可視化することができる。
ノードを作成するには、CREATE文を使用する。例えば、User というラベルを持つノードを作成する場合は次のようになる。
|
|
ノードを検索するには、MATCH文を使用し、例えば先ほど作成した名前が ‘Mike’ のユーザーを検索する場合は次のようになる。
|
|
エッジの作成を試すためノードを追加する。
|
|
その後、ユーザー間の「FRIEND」関係を表すエッジを作成する場合は、以下のような CREATE文を使用する。
|
|
名前が ‘Mike’ のユーザーの「FRIEND」関係を検索する場合は次のようになる。
|
|
エッジを削除するには、MATCH 文と DELETE 文を組み合わせて使用する。名前が ‘Mike’ のユーザーと ‘Tom’ のユーザー間の友達関係を削除する場合は以下である。
|
|
ノードを削除するには、MATCH 文と DELETE 文を組み合わせて使用する。具体的に、名前が ‘Mike’ のユーザーを削除する場合は次のようになる。
|
|
Neo4j の特徴
Neo4j はトランザクションの概念を有しており、ACID 特性を満たすことができる。しかし、グラフというデータの繋がりを格納するデータベースであることから、レコードを分割することが困難であり、分散管理は不得意である。
パフォーマンス
ディスク上の永続的なログとメモリ上のキャッシュを利用することで、効率的にデータの書き込みと読み込みを行っている。全ての書き込み処理は、ディスク上のログに書き込まれることから、ACID 特性の Durability 永続性を担保している。 特定のラベルとプロパティに対してインデックスを作成することが可能である。CREATE INDEX 文を使用し、User ラベルの name プロパティに対してインデックスを作成する場合は次のようになる。
|
|
作成されたインデックスを確認するには、SHOW INDEXES 文を使用する。
|
|
可用性
分散管理が得意なデータベースではないが、トランザクションの概念があることから、プライマリーの処理をセカンダリに同期するようなレプリケーションを行うことが可能である。
トランザクション
ある程度意味の塊の操作群をトランザクションとして扱い、ノードもしくはエッジ単位でロックを保持することで、トランザクションを実現している。コミットされると、その内容がディスクに書き込まれる。デフォルトのトランザクション独立レベルは Read Committed になるため、同じトランザクション内で同じデータを読み込んだ際に値が異なる Non-Repeatable Read が生じる可能性がある。
Reflection
今までグラフデータベースに関しては全くイメージができなかったが、今回 Neo4j を構築し実際に触れたことで、利用方法に関してイメージを得ることができた。 しかしながら、様々な方向に広がる可能性のあるグラフデータに関して、どのような形式で保存されているのかは気になった。リレーショナルデータベースであればデータが page に格納され、行が挿入されていくため、データの取得含めてイメージがしやすいが、グラフデータだとどうなるのか想像がつかない。そのため、今後はそこを調べていきたい。