グラフ型データベースで社員のつながりを可視化する

# 1. グラフ型データベースの概要
グラフ型データベースとは、`(キアヌリーブス)-[出演]->(マトリックス)`
のような情報を取り扱うNoSQLの一種のデータベースです。

例：俳優と出演映画の関係
![Cq2aKvKVIAAVF6k.jpg](https://qiita-image-store.s3.amazonaws.com/0/124069/3924d416-1600-2c71-012c-a7f0c1c4eebc.jpeg)

今回はグラフ型データベースの一つ「[Neo4j](https://neo4j.com/)」のウェブインターフェースを使って、

- プロジェクトに参加している人がどんな研修に参加しているのか
- プロジェクト外でどんなつながりがあるのか

などを可視化してみたいと思います。
（登場する人名、プロジェクト名などはすべて架空です）

- 参考リンク
 - [neo4j - クリエーションライン株式会社](http://www.creationline.com/neo4j) (日本語によるNeo4jの説明)

# 2. 環境設定
私の場合は、Windows 10、Neo4j community版 ver3.0.4（無償）の環境を構築しました。

- 参考リンク
 - [ダウンロード元](https://neo4j.com/download/)
 - [WindowsでNeo4jを使ってみる](http://qiita.com/awk256/items/5622d601c2c3051b70ad)
 - [neo4j - クリエーションライン株式会社](http://www.creationline.com/neo4j) (日本語によるNeo4jの説明)

# 3. データ投入
データ投入のためのCypherクエリです。ウェブインターフェイスから投入しました。
少し長いのでここでは抜粋版を記載します。

```text:データ投入用Cypherクエリ
// ノード「人」の追加
CREATE (morinaga:Person { name: "森永"})
CREATE (nagase:Person { name: "長瀬"})

// ノード「プロジェクト」の追加
CREATE (pja:Project { name: "A社稟議システム開発"})
CREATE (pjb:Project { name: "B社備品管理システム開発"})

// ノード「研修」の追加
CREATE (python:Seminar { name: "Python研修"})
CREATE (aspnet:Seminar { name: "ASP.NET研修"})

// ノード「イベント」の追加
CREATE (hanami:Event { name: "花見"})
CREATE (christmas:Event { name: "バーべキュー"})

// リレーション「研修への参加」を追加
CREATE (pja) <-[:参加]-(morinaga)
CREATE (pja) <-[:参加]-(nagase)

// リレーション「研修への参加」を追加
CREATE (python) <-[:参加]-(oodaira)
CREATE (python) <-[:参加]-(nagase)

// リレーション「イベントへの参加」を追加
CREATE (hanami) <-[:参加]-(fujisawa)
CREATE (hanami) <-[:参加]-(sekine)
```

確認のためにノードとリレーションをすべて表示します。

```text:データ表示クエリ
MATCH (n) OPTIONAL MATCH (n)-[r]-()
RETURN n,r
```
以下のような結果になります。
![graph.png](https://qiita-image-store.s3.amazonaws.com/0/124069/343214ba-bce4-de18-ed9c-0415ed2434f3.png)

# 4. つながりを可視化する
## 4.1. 特定のプロジェクトに参加した人を可視化する
まずは単純に、プロジェクト「A社稟議システム開発」に参加した人を可視化します。

```text:データ表示クエリ
MATCH (pj:Project{name:"A社稟議システム開発"})<-[r:参加]-(p:Person)
RETURN pj,r,p
```
【結果】
4人が参加したことが分かりました。
![graph (1).png](https://qiita-image-store.s3.amazonaws.com/0/124069/391b36b4-b78b-77fc-7ab3-598203249f5d.png)
 
## 4.2. 「このプロジェクトに参加している人はこんなプロジェクトにも参加しています」
「C社認証基盤システム構築」に参加した人が、他にどんなプロジェクトに参加したかを可視化します。

```text:データ表示クエリ
MATCH (pj1:Project{name:"C社認証基盤構築"})<-[r1:参加]-(p:Person) 
OPTIONAL MATCH (p)-[r2:参加]->(pj2:Project)
RETURN pj1,r1,r2,pj2
```

【結果】
永井さんが「D社NW機器リプレース」にも参加したことがわかります。インフラが得意なのかもしれませんね。
![graph (2).png](https://qiita-image-store.s3.amazonaws.com/0/124069/ff4265d6-6084-5763-c281-fa4e387d23f7.png)

## 4.3. 「このプロジェクトに参加している人はこんな研修に参加しています」
「B社備品管理システム開発」に参加した人が、どんな研修に参加したか可視化します。

```text:データ表示クエリ
MATCH (pj1:Project{name:"B社備品管理システム開発"})<-[r1:参加]-(p:Person) 
OPTIONAL MATCH (p)-[r2:参加]->(s:Seminar)
RETURN pj1,r1,r2,s
```

【結果】
ASP.NET研修に参加したことが分かりました。B社備品管理システムはASP.NETで構築されているのかもしれません。
![graph.png](https://qiita-image-store.s3.amazonaws.com/0/124069/a2bc8ddb-8b7c-c826-4e2e-2cecfa8b5e42.png)


## 4.4. プロジェクト外でどんなつながりがあるのか

坂上さんがプロジェクト外の人とどんなつながりがあるかを可視化します。
つながりのリレーション数は2までにしています。

```text:データ表示クエリ
MATCH (p1:Person{name:"坂上"})-[*0..2]-(p2)
OPTIONAL MATCH (p2)-[:参加]->(pj:Project)
RETURN　p1,p2,pj
```

【結果】
プロジェクト外の様々な人と、マラソン大会に参加でつながっていることがわかりました。
![graph (1).png](https://qiita-image-store.s3.amazonaws.com/0/124069/bfc2500a-d267-d2ce-a7bd-fecd7bfc8dbb.png)


# 5. おわりに
RDBでもこのようなつながりを扱うことも可能といえば可能ですが、グラフ型データベースでは簡単に扱うことができます。
この仕組みを使って、RDBではできない、または難しかった関係を表現して新たな発見ができるとよいなと思いました。

最後の最後にデータ投入クエリの完全版です。

```text
// ノード「人」の追加
CREATE (morinaga:Person { name: "森永"})
CREATE (nagase:Person { name: "長瀬"})
CREATE (nagai:Person { name: "永井"})
CREATE (nakao:Person { name: "中尾"})
CREATE (sakagami:Person { name: "坂上"})
CREATE (fujisawa:Person { name: "藤沢 "})
CREATE (sekine:Person { name: "関根"})
CREATE (oodaira:Person { name: "大平 "})
CREATE (nohara:Person { name: "野原"})
CREATE (inagaki:Person { name: "稲垣 "})

// ノード「プロジェクト」の追加
CREATE (pja:Project { name: "A社稟議システム開発"})
CREATE (pjb:Project { name: "B社備品管理システム開発"})
CREATE (pjc:Project { name: "C社認証基盤構築"})
CREATE (pjd:Project { name: "D社NW機器リプレース"})

// ノード「研修」の追加
CREATE (python:Seminar { name: "Python研修"})
CREATE (aspnet:Seminar { name: "ASP.NET研修"})
CREATE (linux:Seminar { name: "Linux研修"})
CREATE (ad:Seminar { name: "ActiveDirectory研修"})
CREATE (network:Seminar { name: "ネットワーク研修"})

// ノード「イベント」の追加
CREATE (hanami:Event { name: "花見"})
CREATE (christmas:Event { name: "バーべキュー"})
CREATE (golf:Event { name: "ゴルフ大会"})
CREATE (marathon:Event { name: "マラソン大会"})

// リレーション「研修への参加」を追加
CREATE (pja) <-[:参加]-(morinaga)
CREATE (pja) <-[:参加]-(nagase)
CREATE (pja) <-[:参加]-(oodaira)
CREATE (pja) <-[:参加]-(nohara)
CREATE (pjb) <-[:参加]-(morinaga)
CREATE (pjb) <-[:参加]-(nakao)
CREATE (pjb) <-[:参加]-(sakagami)
CREATE (pjc) <-[:参加]-(nagai)
CREATE (pjc) <-[:参加]-(fujisawa)
CREATE (pjd) <-[:参加]-(nagai)
CREATE (pjd) <-[:参加]-(sekine)
CREATE (pjd) <-[:参加]-(inagaki)

// リレーション「研修への参加」を追加
CREATE (python) <-[:参加]-(oodaira)
CREATE (python) <-[:参加]-(nagase)
CREATE (aspnet) <-[:参加]-(nakao)
CREATE (aspnet) <-[:参加]-(sakagami)
CREATE (linux) <-[:参加]-(nagai)
CREATE (linux) <-[:参加]-(oodaira)
CREATE (linux) <-[:参加]-(nohara)
CREATE (ad) <-[:参加]-(fujisawa)
CREATE (network) <-[:参加]-(sekine)
CREATE (network) <-[:参加]-(inagaki)

// リレーション「イベントへの参加」を追加
CREATE (hanami) <-[:参加]-(fujisawa)
CREATE (hanami) <-[:参加]-(sekine)
CREATE (christmas) <-[:参加]-(fujisawa)
CREATE (christmas) <-[:参加]-(nakao)
CREATE (golf) <-[:参加]-(morinaga)
CREATE (marathon) <-[:参加]-(morinaga)
CREATE (marathon) <-[:参加]-(nagase)
CREATE (marathon) <-[:参加]-(nagai)
CREATE (marathon) <-[:参加]-(nakao)
CREATE (marathon) <-[:参加]-(sakagami)
CREATE (marathon) <-[:参加]-(fujisawa)
CREATE (marathon) <-[:参加]-(sekine)
CREATE (marathon) <-[:参加]-(oodaira)


```