メインコンテンツまでスキップ

第 2 章: Cypher の世界へようこそ

環境構築と最初のクエリ

Cypher ASCII Art Concept

理論の前に、まずは実際に手を動かして Cypher に触れてみましょう。ここでは、ローカル環境とクラウド環境の 2 つの選択肢を紹介します。どちらも無料で始めることができ、開発ライフサイクルの異なる段階でそれぞれの利点があります。

2.1 学習環境の準備

オプション A: Neo4j Desktop(ローカル開発環境)

Neo4j Desktop は、自身の PC 上で Neo4j データベースを管理するためのクライアントアプリケーションです。オフラインでの作業や、複数のプロジェクトを個別に管理したい場合に最適で、開発者のための「サンドボックス」として機能します。

Neo4j Desktop Setup Flow

セットアップ手順:

  1. Neo4j の公式サイトから Neo4j Desktop をダウンロードし、インストールします
  2. アプリケーションを起動し、新しいプロジェクトを作成します
  3. プロジェクト内で「Add Database」をクリックし、「Local Database」を選択します
  4. データベース名とパスワードを設定し、「Create」ボタンを押します
  5. 作成されたデータベースの「Start」ボタンを押し、起動します

オプション B: Neo4j AuraDB Free(クラウドベース環境)

Neo4j AuraDB は、Neo4j 社が提供するフルマネージドのクラウドデータベースサービスです。Free Tier(無料枠)を利用すれば、インストールの手間なく、数分でグラフデータベースを使い始めることができます。

AuraDB Cloud Setup

セットアップ手順:

  1. console.neo4j.io にアクセスし、アカウントを登録します
  2. ログイン後、「New Instance」をクリックし、「Create Free instance」を選択します
  3. インスタンスがプロビジョニングされると、接続情報(URI、ユーザー名、パスワード)が表示されます
  4. この情報は後で利用するため、必ず安全な場所に保存してください

無料枠の制限: ノード数 20 万件、リレーションシップ数 40 万件

どちらの環境を選んでも、操作は「Neo4j Browser」という Web ベースのインターフェースを通じて行います。Neo4j Desktop では起動したデータベースの「Open」ボタンから、AuraDB ではコンソールの「Query」ボタンからアクセスできます。

2.2 サンプルデータのインポート

チュートリアル全体を通して使用する、架空のコンサルティング会社「walk-with-ai」の業務シナリオを想定したサンプルデータを作成します。

Sample Data Model

このデータは、Company(会社)、Employee(従業員)、Project(プロジェクト)、Skill(スキル)といったエンティティ(ノード)と、それらの間の関係性を表現しています。

以下の Cypher スクリプトをコピーし、Neo4j Browser のクエリ入力欄に貼り付けて実行してください:

// 既存のデータをすべて削除して初期状態にします
MATCH (n) DETACH DELETE n;

// 会社ノードを作成
CREATE (:Company {name: "A社", industry: "製造業"})
CREATE (:Company {name: "B社", industry: "IT"})
CREATE (:Company {name: "C社", industry: "金融"})

// 従業員ノードを作成
CREATE (:Employee {name: "佐藤", title: "マネージャー", experience: 8})
CREATE (:Employee {name: "鈴木", title: "エンジニア", experience: 5})
CREATE (:Employee {name: "高橋", title: "アナリスト", experience: 3})
CREATE (:Employee {name: "田中", title: "エンジニア", experience: 7})
CREATE (:Employee {name: "伊藤", title: "プロジェクトマネージャー", experience: 10})

// プロジェクトノードを作成
CREATE (:Project {name: "AI導入支援", status: "進行中", budget: 5000000})
CREATE (:Project {name: "DX戦略策定", status: "完了", budget: 3000000})
CREATE (:Project {name: "サプライチェーン最適化", status: "計画中", budget: 8000000})

// スキルノードを作成
CREATE (:Skill {name: "Python", category: "プログラミング"})
CREATE (:Skill {name: "機械学習", category: "AI/ML"})
CREATE (:Skill {name: "データ分析", category: "分析"})
CREATE (:Skill {name: "Cypher", category: "データベース"})
CREATE (:Skill {name: "プロジェクト管理", category: "マネジメント"})

// リレーションシップを作成
// 従業員-会社間の関係
MATCH (e:Employee {name: "佐藤"}), (c:Company {name: "A社"})
CREATE (e)-[:WORKS_FOR {since: 2020}]->(c)

MATCH (e:Employee {name: "鈴木"}), (c:Company {name: "A社"})
CREATE (e)-[:WORKS_FOR {since: 2021}]->(c)

MATCH (e:Employee {name: "高橋"}), (c:Company {name: "A社"})
CREATE (e)-[:WORKS_FOR {since: 2022}]->(c)

MATCH (e:Employee {name: "田中"}), (c:Company {name: "B社"})
CREATE (e)-[:WORKS_FOR {since: 2019}]->(c)

MATCH (e:Employee {name: "伊藤"}), (c:Company {name: "C社"})
CREATE (e)-[:WORKS_FOR {since: 2018}]->(c)

// 管理関係
MATCH (mgr:Employee {name: "佐藤"}), (emp:Employee {name: "鈴木"})
CREATE (mgr)-[:MANAGES {since: 2023}]->(emp)

MATCH (mgr:Employee {name: "佐藤"}), (emp:Employee {name: "高橋"})
CREATE (mgr)-[:MANAGES {since: 2023}]->(emp)

// プロジェクト参加関係
MATCH (e:Employee {name: "鈴木"}), (p:Project {name: "AI導入支援"})
CREATE (e)-[:PARTICIPATES_IN {role: "開発者"}]->(p)

MATCH (e:Employee {name: "高橋"}), (p:Project {name: "AI導入支援"})
CREATE (e)-[:PARTICIPATES_IN {role: "アナリスト"}]->(p)

MATCH (e:Employee {name: "佐藤"}), (p:Project {name: "DX戦略策定"})
CREATE (e)-[:PARTICIPATES_IN {role: "プロジェクトリーダー"}]->(p)

MATCH (e:Employee {name: "伊藤"}), (p:Project {name: "サプライチェーン最適化"})
CREATE (e)-[:PARTICIPATES_IN {role: "プロジェクトマネージャー"}]->(p)

// スキル保有関係
MATCH (e:Employee {name: "鈴木"}), (s:Skill {name: "Python"})
CREATE (e)-[:HAS_SKILL {level: "上級"}]->(s)

MATCH (e:Employee {name: "鈴木"}), (s:Skill {name: "機械学習"})
CREATE (e)-[:HAS_SKILL {level: "中級"}]->(s)

MATCH (e:Employee {name: "高橋"}), (s:Skill {name: "データ分析"})
CREATE (e)-[:HAS_SKILL {level: "上級"}]->(s)

MATCH (e:Employee {name: "高橋"}), (s:Skill {name: "Cypher"})
CREATE (e)-[:HAS_SKILL {level: "初級"}]->(s)

MATCH (e:Employee {name: "佐藤"}), (s:Skill {name: "プロジェクト管理"})
CREATE (e)-[:HAS_SKILL {level: "上級"}]->(s)

MATCH (e:Employee {name: "佐藤"}), (s:Skill {name: "データ分析"})
CREATE (e)-[:HAS_SKILL {level: "中級"}]->(s)

MATCH (e:Employee {name: "田中"}), (s:Skill {name: "Python"})
CREATE (e)-[:HAS_SKILL {level: "上級"}]->(s)

MATCH (e:Employee {name: "伊藤"}), (s:Skill {name: "プロジェクト管理"})
CREATE (e)-[:HAS_SKILL {level: "エキスパート"}]->(s)

2.3 Cypher の基本構文:MATCH と RETURN

Cypher の核となる考え方は「パターンマッチング」です。まるでアスキーアートで絵を描くように、探したいデータの「形」をクエリとして記述します。

Cypher Pattern Syntax

基本要素の説明

ノード (): 丸括弧 () はノードを表します。() の中に e:Employee と書くことで、「Employee というラベルを持ち、e という変数名で参照するノード」という意味になります。

リレーションシップ -->: 角括弧 [] とハイフン -、矢印 > を組み合わせることでリレーションシップを表します。-[:WORKS_FOR]-> は、「左から右へ向かう WORKS_FOR というタイプのリレーションシップ」を意味します。

これらを組み合わせることで、(e:Employee)-[:WORKS_FOR]->(c:Company) というパターンが完成します。これは平易な言葉で言えば、「ある会社に勤務している従業員」という関係性を表現しています。

2.4 最初のクエリ

それでは、最初のクエリを実行してみましょう。以下のクエリは、データベース内に存在する「従業員が会社に勤務している」というパターンをすべて見つけ出し、従業員と会社の名前を返すものです。

// 全ての従業員と、その従業員が勤務する会社を検索する
MATCH (e:Employee)-[:WORKS_FOR]->(c:Company)
RETURN e.name AS employeeName, c.name AS companyName

以下のような書き方もできる

MATCH p=()-[:WORKS_FOR]->() RETURN p; //LIMIT 25などとつけると、結果を制限できる

Query Execution Flow

実行と結果の確認

このクエリを Neo4j Browser に入力し、実行ボタン(▶)をクリックしてください。結果は 2 つの形式で表示されます:

Graph View(グラフビュー): クエリにマッチしたノードとリレーションシップが、視覚的なグラフとして表示されます。どの従業員がどの会社に線で結ばれているか、一目で理解できます。

Table View(テーブルビュー): RETURN 句で指定した e.namec.name が列として表示される、RDB でおなじみの表形式の結果です。

Neo4j Browser がこの 2 つのビューを同時に提供するのは、意図的な設計です。RDB に慣れた開発者が、まず見慣れたテーブル形式でクエリの結果を検証できる安心感を提供しつつ、同時にグラフとしての視覚的な表現を見せることで、自然と「グラフで考える」思考法へと導く、優れた学習ツールとして機能しています。

2.5 より実践的なクエリ例

基本的なパターンマッチングを理解したところで、少し複雑なクエリを試してみましょう。

例 1: 特定の条件でフィルタリング

// A社に勤務するエンジニアを検索
MATCH (e:Employee)-[:WORKS_FOR]->(c:Company {name: "A社"})
WHERE e.title = "エンジニア"
RETURN e.name, e.title, e.experience

例 2: 複数のパターンを組み合わせ

// プロジェクトに参加し、かつスキルを持つ従業員を検索
MATCH (e:Employee)-[:PARTICIPATES_IN]->(p:Project)
MATCH (e)-[:HAS_SKILL]->(s:Skill)
RETURN e.name, p.name, s.name

Complex Query Pattern

例 3: 集計を使った分析

// 各会社の従業員数をカウント
MATCH (e:Employee)-[:WORKS_FOR]->(c:Company)
RETURN c.name, count(e) AS employeeCount
ORDER BY employeeCount DESC

これらの例を通じて、Cypher が如何に直感的で表現力豊かな言語であるかを実感いただけたでしょう。次の章では、これらの基本概念を基に、データの作成、更新、削除といったより実践的な操作を学んでいきます。


前へ: 第 1 章: なぜ今、グラフデータベースなのか? | 次へ: 第 3 章: 知識グラフを育てる

関連記事

著者: hnish