こんにちは、技研の「むらたん」です。 ※のむらたんに読めるというクレームを受けて、カッコつけました。

 

技術研究所では毎年12月に有志社員を募り、(社内限定公開の)Advent Calendarを開催しているのですが、エンジニアブログのオープン記念ということで、私のエントリーはエンジニアブログに書いてみようかと思います。
最近の技術的な関心事は「グラフデータベース」で、使い方や可能性を自由研究しています。

グラフデータベースとは

グラフデータベースの「グラフ」とは、円グラフとか折れ線グラフのようなデータを可視化するツールではなく、「頂点」と「辺」の集合のことを指しており、それをデータモデリングで使ったものがグラフデータベースになります。
facebookやtwitterのような、SNS上のアカウントを頂点、フォローの関係を辺にとして、つながりを表したものは「ソーシャルグラフ」なんて呼ばれたりします。
「データベース」といえば「関係データベース(RDB)」という印象がありますが、RDBはデータやトランザクションの整合性を担保することに長けている反面、データの関係を表現・抽出することには不向きです。RDBの苦手な部分を解消する技術として、NoSQLもありますが、Key-Valueの考え方が根底にあるため、RDBと同じようにデータの関係を表現することは苦手です。
#RDBのRは「Relational=関係」ですが、皮肉ですね。

ここでいう「関係」はRDBが得意とする「1つの意味を表すもの」を「複数の正規化された情報を関連付けて」表現することではなく、「1つの意味を表すもの同士のつながり」のことを指します。
例えるなら、1つの意味を表すものは「販売帳票」であり、1つの意味を表すもの同士のつながりは「レコメンド(販売帳票の中のこの商品を購入された方は、こちらの商品も購入されています)」です。グラフデータベースはこんなところで使える技術になります。

グラフデータベースを使ってみる

ここからは、オープンソースのグラフデータベースエンジンであるでNeo4jで色々とやってみたいと思います。

Neo4j概要

データベースとしての特徴

  • グラフの頂点をノードと呼ぶ
  • ノードにはラベルを貼ることができ、ノードの種別を持つことができる
  • 一つのノードに複数のラベルを貼ることができる
  • グラフの辺をリレーションと呼び、ノード同士を関連づけることができる
  • リレーションには向きがある。双方向を表現するには、2つのリレーションで表現する
  • ノード、リレーションともkey-Value形式のプロパティを持てる

製品としての特徴

  • ACIDの保証と高い可用性がある
  • データ量が増えても性能劣化が起こりにくい
  • Webインタフェースが提供されており、グラフを視覚的に見ることができる
  • REST APIが提供されている

Neo4jのセットアップ

1.ソフトの入手とインストール
Neo4jのサイトに行き、Donwload → Community Edition → OS(今回はWindowsのexe形式)を選択します。
ダウンロードしたをexeファイルを全てデフォルトでインストールします。

2.データベースの起動
データベース情報を格納する物理ファイルのパスを指定し、Startボタンを押したら、起動完了です。
ブラウザからhttp://localhost:7474/ でアクセスできます。

Cypherについて

Cypher(サイファー)とは

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のキーワードは「由来」です。

最後までお付き合いいただき、ありがとうございました。