Neo4jをはじめよう！グラフデータベースで最初のクエリを書くまで

# 1. 初めに
[MYJLab Advent Calendar 2024](https://qiita.com/advent-calendar/2024/myjlab)　の8日目の担当するM1の浦です。

最近は就活に追われており、記事を絶望しながら書いております、、、

この記事では、グラフデータベースのNeo4jを初めて触れる方向けに、基本的な概念からセットアップ方法、簡単なクエリの実行までを解説しようと思います。

## 2. グラフデータベースとは？

グラフデータベースとは、頂点（vertex）と辺（edge）から構成されるデータ構造を備えたデータベースのこと。従来のリレーショナルデータベースとは異なり、データ同士の繋がりを表現するグラフ構造に基づいてデータを格納する。これにより、ネットワーク状のデータ構造を効率的に格納・検索することが可能。

### 主要概念
- **ノード（Node）**: データのエンティティやオブジェクトを表す
- **エッジ（Edge）**: ノード間の関係を表し、方向性を持つことがある
- **プロパティ（Property）**: ノードやエッジに付加される属性情報

![主要な概念.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/b6aa924d-a9fd-ec56-cf05-d6a1c641a748.png)


### 特徴
- **柔軟性**: グラフモデルのスキーマと構造はグラフ構造を事前に定義する必要がなく、既存のグラフ構造を追加・変更しても、既存の機能に影響を与えることなく運用できる
- **高速なパフォーマンス**: リレーショナルデータベースではリレーションシップが増えるとパフォーマンスが低下する一方、グラフデータベースではリレーションシップの量が増えてもパフォーマンスは一定を保つ。データ間のリレーションシップは永続的にデータベース内に保存されているため、クエリ結果を高速に取得できる

## 3. Neo4jのデスクトップ版のDBMSの作成方法について

デスクトップ版でのセットアップ方法について記載する。

1. [公式サイト](https://neo4j.com/download/)からNeo4j Desktopをダウンロード
2. インストール後、アプリを起動してCreate projectでプロジェクトの作成。Neo4jでは扱いたいDBMSをProjectで紐付ける
![create project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/e11cdeb0-28c8-4ee5-fae6-1a506f0365ff.png)

3. Addボタンを押しLocal DBMSの作成
![add.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/678fe2fb-9e98-849e-0260-342c5228a17e.png)
4. 新規作成のDBMSにはアクセスするためのパスワードが必要。入力後DBMSが作成される
![pas.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/e7f34808-349a-b124-5bd0-ebc372c141ee.png)
5. 作成したDBMSを操作する画面を開くにはStartを押すとDBMSが準備され実行開始される
![start.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/2b0f056a-c474-ca24-9f1e-920c96aeecdd.png)
5. ACTIVE表記になったらOpenを押す。
![open.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/804ad1fe-d8a0-956d-63c8-ed58e9208132.png)
6. 最後に別ウィンドドウが立ち上がったら完了。この画面ではCypher言語を用いてこのDBMSを操作することができ、その結果をグラフィカルに見ることができる
![neo4jgamenn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/e2b64dc9-969a-7503-d266-f2b864fe5462.png)

## 4. 基本的なCypherクエリの書き方とその結果
画面

Neo4jでは、Cypherという独自のクエリ言語を使用します。以下の基本構文を覚えよう。

### 4.1 ノードの作成
```cypher
CREATE (a:Person {name: 'Alice', age: 30})
CREATE (b:Person {name: 'Bob', age: 35});
```
このままでは下記の写真の何も表示されない
![alice1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/41b654ab-c803-a04c-116d-c5714770a7f6.png)

### 4.2 現在のデータベース全体の可視化
```cypher
MATCH(n)OPTIONAL MATCH(n)-[r]-()RETURN n,r
```
先ほど作ったノードが表示される
![kashika.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/535df4a3-d019-b845-a480-72116edd8e7c.png)
### 4.3 リレーションシップの作成
```cypher
MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'})
CREATE (a)-[:FRIEND]->(b);
```
このままではノードの関係がないのでリレーションシップを作成する。AliceからBobへのFREINDの関係が作成される。
![friend.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/f4f82581-f363-f21f-449f-b87c9285a2fe.png)

### 4.4 データベース中の全データ削除
```cypher
MATCH(n)OPTIONAL MATCH(n)-[r]-()DELETE n,r
```
![sakuzyo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/de81b10e-3eda-d761-87c5-53d7fe97e2f3.png)
下記のコマンドを入力して何も表示されなければ削除完了
```cypher
MATCH(n)OPTIONAL MATCH(n)-[r]-()RETURN n,r
```
![kieta.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/175118a3-a626-c0f4-2235-87c96f97fbff.png)


## 5. サンプルデータを用いたクエリ

Neo4jには「映画データベース」というサンプルデータが用意されています。これを活用して練習できる。

### 5.1 映画データベースのインポート
```cypher
:play movies
```
チュートリアルが表示されるので、指示に従ってデータベースをセットアップする。下記の画面が出たら完了。
![movies.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/22afd993-625a-70cb-9ec7-c19966720332.png)

### 5.2 ノードやプロパティの検索
トム・ハンクスを検索
```cypher
MATCH (tom {name: "Tom Hanks"}) RETURN tom
```
1990年代の映画を検索
```cypher
MATCH (nineties:Movie) WHERE nineties.released >= 1990 AND nineties.released < 2000 RETURN nineties.title
```
![1990.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/f5d56df4-6c8d-1815-1467-2c79328f3d37.png)

### 5.3 ノード間の関係検索
トム・ハンクスが出演した映画
```cypher
MATCH (tom:Person {name: "Tom Hanks"})-[:ACTED_IN]->(movies) RETURN movies.title

```
「クラウド・アトラス」の監督を検索
```cypher
MATCH (nineties:Movie) WHERE nineties.released >= 1990 AND nineties.released < 2000 RETURN nineties.title
```

### 5.4 最短経路を計算する例
ケビン・ベーコンとメグ・ライアン間の最短経路
```cypher
MATCH p=shortestPath(
  (bacon:Person {name:"Kevin Bacon"})-[*]-(meg:Person {name:"Meg Ryan"})
)
RETURN p
```
![saitan.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/0b17393d-5332-f3c8-507e-53bf81cd12d0.png)

### 5.5 コネクションを活用した推薦
トム・ハンクスの新しい共演者を探す
```cypher
MATCH (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors),
      (coActors)-[:ACTED_IN]->(m2)<-[:ACTED_IN]-(potentialCoActors)
WHERE NOT (tom)-[:ACTED_IN]->()<-[:ACTED_IN]-(potentialCoActors) AND tom <> potentialCoActors
RETURN potentialCoActors.name AS Recommended, COUNT(*) AS Strength ORDER BY Strength DESC
```
![shitashii.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983787/a747b157-3766-4d80-9064-8565e44102a9.png)


## 6. 次のステップ

- 自分のデータを使ってグラフデータベースを構築
- Cypherの高度なクエリやNeo4jのAPI連携を学ぶ

Neo4jを使うことで、データの関係性を可視化し、直感的に操作できる楽しさを感じてください！