こんにちは、技研の「むらたん」です。 ※のむらたんに読めるというクレームを受けて、カッコつけました。
技術研究所では毎年12月に有志社員を募り、(社内限定公開の)Advent Calendarを開催しているのですが、エンジニアブログのオープン記念ということで、私のエントリーはエンジニアブログに書いてみようかと思います。
最近の技術的な関心事は「グラフデータベース」で、使い方や可能性を自由研究しています。
グラフデータベースの「グラフ」とは、円グラフとか折れ線グラフのようなデータを可視化するツールではなく、「頂点」と「辺」の集合のことを指しており、それをデータモデリングで使ったものがグラフデータベースになります。
facebookやtwitterのような、SNS上のアカウントを頂点、フォローの関係を辺にとして、つながりを表したものは「ソーシャルグラフ」なんて呼ばれたりします。
「データベース」といえば「関係データベース(RDB)」という印象がありますが、RDBはデータやトランザクションの整合性を担保することに長けている反面、データの関係を表現・抽出することには不向きです。RDBの苦手な部分を解消する技術として、NoSQLもありますが、Key-Valueの考え方が根底にあるため、RDBと同じようにデータの関係を表現することは苦手です。
#RDBのRは「Relational=関係」ですが、皮肉ですね。
ここでいう「関係」はRDBが得意とする「1つの意味を表すもの」を「複数の正規化された情報を関連付けて」表現することではなく、「1つの意味を表すもの同士のつながり」のことを指します。
例えるなら、1つの意味を表すものは「販売帳票」であり、1つの意味を表すもの同士のつながりは「レコメンド(販売帳票の中のこの商品を購入された方は、こちらの商品も購入されています)」です。グラフデータベースはこんなところで使える技術になります。
ここからは、オープンソースのグラフデータベースエンジンであるでNeo4jで色々とやってみたいと思います。
- グラフの頂点をノードと呼ぶ
- ノードにはラベルを貼ることができ、ノードの種別を持つことができる
- 一つのノードに複数のラベルを貼ることができる
- グラフの辺をリレーションと呼び、ノード同士を関連づけることができる
- リレーションには向きがある。双方向を表現するには、2つのリレーションで表現する
- ノード、リレーションともkey-Value形式のプロパティを持てる
- ACIDの保証と高い可用性がある
- データ量が増えても性能劣化が起こりにくい
- Webインタフェースが提供されており、グラフを視覚的に見ることができる
- REST APIが提供されている
1.ソフトの入手とインストール
Neo4jのサイトに行き、Donwload → Community Edition → OS(今回はWindowsのexe形式)を選択します。
ダウンロードしたをexeファイルを全てデフォルトでインストールします。
2.データベースの起動
データベース情報を格納する物理ファイルのパスを指定し、Startボタンを押したら、起動完了です。
ブラウザからhttp://localhost:7474/ でアクセスできます。
Neo4jを操作するクエリ言語です。詳しくはこちらにマニュアルがあります。
軽く触るぐらいであれば、以下のCypherQLを覚えましょう。
create ( :アニメ{title: "ドラゴンボール"} ) |
コマンド | 意味 |
---|---|
create() | ノードの作成 |
:アニメ | ノードに付与されるラベル |
{} | プロパティをカンマ区切りで定義する |
title: | プロパティキー |
“ドラゴンボール” | プロパティ値 |
ちなみに、ノードとリレーションを一気に作成することも出来ます。
create (:声優 {name:"野沢雅子"})-[:演じる]->(:キャラクター {name:"孫悟空"}) |
コマンド | 意味 |
---|---|
-[:演じる]-> | 「演じる」というリレーション |
match (a:アニメ) return a |
コマンド | 意味 |
---|---|
match() | 抽出 |
a | 変数 |
:アニメ | 「アニメ」というラベルが付与されているもの |
return a | 変数の内容を結果として返す |
// リレーションを貼りたいノードをMATCHで抽出して、CREATEする |
match(m:漫画家 {name:"北条司"}) |
match(w:漫画 {title:"シティハンター"}) |
create m-[:執筆した {year_from:1985, year_to:1991}]->w |
// あ、プロパティを間違えてつけちゃった。。。 |
match(m:漫画 {title:"ドラゴンボール"}) create m-[:登場人物]->(:キャラクター {name:"孫御飯"}) |
// 間違えたノードを抽出して、再設定する。 |
MATCH (n {name:"孫御飯"}) set n.name="孫悟飯" |
上記のCypherを使えば、こんなグラフが描けたりします。
問題:孫悟空の声優さんが演じる他のキャラクターは?
// 孫悟空のノードを抽出して chに設定 |
match (ch {name:"孫悟空"}) |
// ch(孫悟空)を演じるノードをvaに設定 |
match (va)-[:演じる]->(ch) |
// vaが演じるキャラをxに設定して、vaとxを返す |
match (va)-[:演じる]->(x) return va,x |
CypherはNeo4jを操作する言語ですが、openCypherと呼ばれるプロジェクトで、言語をオープン化しようとする動きがあり、Neo4jを提供するNeo Technologyに加え、OracleやTableauといった会社も名を連ねています。
CypherもSQLと肩を並べる業界標準になる日が来るかもしれません。
Advent Calendar ではキーワードクイズをしています。 ※社員限定イベントです。
12/17のキーワードは「由来」です。
最後までお付き合いいただき、ありがとうございました。