こんにちは、技研の「むらたん」です。 ※のむらたんに読めるというクレームを受けて、カッコつけました。
技術研究所では毎年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のキーワードは「由来」です。
最後までお付き合いいただき、ありがとうございました。


