search
LoginSignup
15
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

Neo4j Advent Calendar 2016 Day 18

posted at

updated at

Cypherのリレーションシップ(Relationship)の基本を理解する

Neo4jのCypherクエリ、サンプルは豊富にあるのですが、記法がちょっとわかりづらいです。今回は、ノード(Node)に引き続き、リレーションシップ(Relationship)を見ていきます。ノード編で紹介した記法を理解している前提で説明します。

作成

aとbのノードの間に、タイプがAAAのリレーションシップを作成します。

MATCH (a:....)            // ノードを任意の条件で検索し、aとする
MATCH (b:....)            // ノードを任意の条件で検索し、bとする
CREATE (a)-[:AAA]->(b)

始端終端ノード (必須)

  • MATCHの検索結果を、変数(識別子)で参照させます。
  • ()の中にラベルやプロパティを書くと、ノードが新規に作成されます。
  • ()の中に何も書かないと、IDだけのノードが作成されます。

同じラベルやプロパティのノードが既に存在していても、CREATE文でラベルやプロパティが書かれていると、ノードが作成されてしまいます。ただし、CREATE UNIQUEを使うと、終端に関しては、同じラベルやプロパティのノードは複製されず、既にあるノードにリレーションシップが作成されます。

方向 (必須)

  • -[:AAA]-><-[:AAA]-で記述します。
  • -[:AAA]-と書くと、エラーとなります。

タイプ (必須)

  • []の中に、:に続けて記述します。
  • -->-[]->と書くと、エラーとなります。

プロパティ(任意)

  • ノードと同様、リレーションシップにもデータを持たせることができます。
  • 記法はノードの場合と同じです。
CREATE (a)-[:AAA{name:'bbb'}]->(b)

識別子 (任意)

  • 作成直後にリレーションシップを参照したい場合は、ノードと同様、(の直後に識別子を書きます。
CREATE (a)-[r:AAA]->(b)      // 変数rで参照可能となる

検索

MATCH p=式 RETURN pに入れる部分を抜き出した形で説明します。

最小限

ありとあらゆるノードの間のパスを検索します。

()--()     // (1) 方向関係なし
()-->()    // (2) 左から右
()<--()    // (3) 右から左

()は、「全部のノード」と覚えておきましょう。

(1)の場合、各ノードが始端と終端に設定されて検索されるため、同じパスが2回ずつ検索結果に含まれることになります。

リレーションシップに識別子をつける

リレーションシップ自体を、後から変数rで参照できるようにします。

()-[r]-()

type(r)で、リレーションシップのタイプ(冒頭の例ではAAA)を取得できます。

始端終端ノードを限定する

MATCHで検索した結果に識別子を割り当てるか、()の中に検索条件を直接書くかして、始端終端ノードを限定した状態でパスを検索できます。

(a)--()    // 両方向
()--(a)    // 上とまったく同じ結果
(a)-->()   // aから他へのパス
(a)<--()   // 他からaへのパス

矢印をつけなければ、リレーションシップの方向に関わらず検索できますので、ノード同士が双方向で繋がっている必要はありません。このため、同じ意味(タイプ、プロパティ)の繫がりであれば、どちらか一方向のリレーションシップだけ作成しておけば充分です。データベース領域の節約になります。

リレーションシップのタイプやプロパティで絞り込む

リレーションシップを作成する時に使った記法を使えば、タイプやプロパティで絞り込み検索ができます。

()-[:AAA]->()           // タイプがAAAのリレーションシップ
()-[{name:'bbb’}]->()   // nameプロパティがbbbのリレーションシップ

複数のタイプを一度に検索できます。

()-[:AAA|BBB]->()        // AAAまたはBBBのリレーションシップ

2ホップ以上のリレーションシップ

間に何かが1つ挟まっているパスを検索します。

({title: 'The Matrix'})--()--({title: 'Cloud Atlas'})

2ホップ

ホップが複数になっても、リレーションシップのタイプやプロパティで絞り込みできます。

({title: 'The Matrix'})-[:DIRECTED]-()-[:DIRECTED]-({title: 'Cloud Atlas'})

2ホップその2

省略記法

タイプやプロパティを指定しない場合、次のように書けます。

(a)-[*2]-(b)     // (a)--()--(b)
(a)-[*3..4]-(b)  // (a)--()--()--(b)または(a)--()--()--()--(b)
(a)-[*3..]-(b)   // (a)--()--()--(b)以上のホップ数
(a)-[*..3]-(b)   // (a)--()--()--(b)以下のホップ数
(a)-[*]-(b)      // ホップ数無制限
(a)-[*0..]-(b)   // ホップ数無制限 (a)のみというパスも含む

全てのホップで同じ条件で良ければ、省略記法でもタイプやプロパティを指定できます。例えば、少し前に出てきた例を書き換えると、こうなります。

({title: 'The Matrix'})-[:DIRECTED*2]-({title: 'Cloud Atlas'})

識別子、:タイプ、*数字、プロパティの順番です。全部入れると、このような感じになります。

()-[r:TYPE*3..4{key:'value'}]-()

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
15
Help us understand the problem. What are the problem?