Neo4j Cypher入門

Cypherとは

Cypherは、Neo4jがデータベースクエリのために開発したグラフクエリ言語である。SQLに似た形式を持ち、強力で多様なデータ表現ができる。

Cypherの例

Neo4jの主要インターフェースとして、パターンとリレーションシップを視覚的に照合する方法を提供する。

Cypherでは(nodes)-[:ARE_CONNECTED_TO]->(otherNodes)のようなパターンを使う。丸括弧()ノード、角括弧[]リレーションシップ-->はノード間のリレーションシップの方向を表す。

表現力と効率に優れたクエリを記述し、グラフデータの作成、読み取り、更新、削除(CRUD)を実行できる。

Cypherの構文

Cypherは人が読みやすいように設計されており、英単語とエンティティを表す図形を使った視覚的な構文を持つ。

Cypherグラフ v1

  • Jenniferはグラフ技術が好きである。
  • Jenniferは2018年からMichaelと友人である。
  • JenniferはNeo4jで働いている。

Cypherのコメント

コメントは//で始め、その後に任意のテキストを記述する。多くのプログラミング言語と同様に、2つのスラッシュ以降、その行の末尾までがコメントになる。

Cypherでノードを表現する

CypherはパターンにASCIIアート1を使用するため、各要素を視覚的に表現する。プロパティグラフモデルの主な要素はノードとリレーションシップである。ノードはグラフ内のデータエンティティで、データモデルの名詞やオブジェクトに相当する。この例ではJennifer、Michael、GraphsがNeo4jのノードである。

Cypherグラフのノード

Cypherでは(node)のように、ノードを丸括弧で囲む。この形はデータモデルの図でノードを表す円に似ている。

ノード変数

後からノードを参照するには、(p:Person)(t:Thing)のように変数を指定する。(person)(thing)のような長く説明的な名前も利用できる。プログラミング言語の変数と同様に名前を選び、以降のクエリで同じ名前を使う。

空の丸括弧()は匿名ノードを表す。ノード自体が戻り値に不要な場合に使う。匿名ノードは後から名前で返すことができない。

ノードラベル

ノードラベルはプロパティグラフ内の類似ノードをグループ化する。ラベルはタグのように機能し、検索または作成するエンティティの種類を指定する。この例ではPersonTechnologyCompanyがラベルである。

ラベルはSQLで検索対象のテーブルを指定することに似ている。SQLがPersonEmployeeCustomerテーブルを対象にできるように、Cypherも対象ラベルだけを検査できる。これによりエンティティを区別し、クエリ実行を最適化できる。可能な場合はノードラベルを使用することを推奨する。

ラベルを指定しない場合、Cypherは無関係なノードを除外するためデータベース内のすべてのノードを確認する。非常に大きなグラフではクエリに時間がかかる。

例:Cypherのノード

()                  // ラベルも変数もない匿名ノード。すべてのノードを参照できる
(p:Person)          // 変数はp、ラベルはPerson
(:Technology)       // 変数はなく、ラベルはTechnology
(work:Company)      // 変数はwork、ラベルはCompany

Cypherでリレーションシップを表現する

グラフデータベースを十分に活用するには、ノード間のリレーションシップも表現する。Cypherでは2つのノード間を矢印-->または<--で示す。リレーションシップの種類やプロパティなどの追加情報は、矢印内の角括弧[]に記述する。

この例ではLIKESWORKS_FORIS_FRIENDS_WITHがノード間のリレーションシップである。

Cypherグラフのリレーションシップ

無方向のリレーションシップは矢印を付けず、2つのダッシュ--で表す。データベースには方向が保存されるが、無方向クエリではCypherが物理的な方向を無視してリレーションシップと接続ノードを検索する。保存方向が不明な場合に柔軟なクエリを記述できる。

データの保存方向と逆方向をクエリに指定すると、Cypherは結果を返さない。方向が不明な場合は無方向のリレーションシップを使用する。

// データは次の方向で保存されている。
CREATE (p:Person)-[:LIKES]->(t:Technology)

// 逆方向のクエリは結果を返さない。
MATCH (p:Person)<-[:LIKES]-(t:Technology)

// 方向が不明な場合は無方向で検索する。
MATCH (p:Person)-[:LIKES]-(t:Technology)

リレーションシップタイプ

リレーションシップタイプは、ラベルがノードをまとめるのと同様にリレーションシップを分類して意味を加える。リレーションシップはノードの接続方法を示し、データモデル内の動作や動詞から識別できる場合が多い。

必要なタイプを自由に定義できるが、動詞や行為に基づく明確な名前が望ましい。不適切な名前はCypherを読みにくくする。適切に命名されたCypherは英文のように読める。

  • [:LIKES] — Jennifer LIKES Graphsのように両側のノードと合わせて意味を持つ。
  • [:IS_FRIENDS_WITH] — Jennifer IS_FRIENDS_WITH Michaelを表す。
  • [:WORKS_FOR] — Jennifer WORKS_FOR Neo4jを表す。

リレーションシップ変数

後から参照するには[r][rel]などの変数を指定する。[likes][knows]のような説明的な名前も使える。後から参照しない場合は----><--で匿名リレーションシップを表す。

たとえば-[rel]->または-[rel:LIKES]->では、変数relを使って後からリレーションシップと詳細を参照できる。

-[LIKES]->のようにタイプ名の前のコロンを省略すると、LIKESは変数になる。タイプが指定されていないため、Cypherはすべてのリレーションシップタイプを検索する。

ノードとリレーションシップのプロパティ

プロパティはノードとリレーションシップに詳細を加える名前と値の組である。Cypherではノードの丸括弧またはリレーションシップの角括弧内に波括弧を置き、その中に名前と値を記述する。例にはノードプロパティnameとリレーションシッププロパティsinceがある。

  • ノードプロパティ:(p:Person {name: 'Jennifer'})
  • リレーションシッププロパティ:-[rel:IS_FRIENDS_WITH {since: 2018}]->

Cypherグラフのプロパティ

プロパティはさまざまなデータ型の値を持てる。完全な一覧はCypherマニュアルの値と型の項を参照する。

Cypherのパターン

ノードとリレーションシップはグラフパターンの構造を形成する。組み合わせることで単純または複雑なパターンを表現できる。Cypherでは連続したパスとして記述するか、小さなパターンに分けてカンマで結合する。

これまで説明したノードとリレーションシップの構文を組み合わせる。たとえばJennifer likes Graphsは次のように表す。

(p:Person {name: "Jennifer"})-[rel:LIKES]->(g:Technology {type: "Graphs"})

この断片は目的のパターンを表すが、既存パターンを検索するのか、新しいパターンを追加するのかは指定していない。操作を指定するにはCypherのキーワードを追加する。

原文


  1. テキストと特殊文字だけを組み合わせて画像や図を表現する手法。 ↩︎