Cypher(サイファー)でCRUDする方法

Neo4jのCypher(サイファー)でCRUDする方法をご紹介します。

作成(Create)

CREATE でノード、リレーションを新規作成できる。

MERGE 重複を許さないCREATE 文

リレーションの作成

MATCH (a:User{name:"Alice"}),(b:User{name:"Bob"}) CREATE (a)-[:FRIEND]->(b);

検索(Read)

構文の例:
全nodeの検索

MATCH (n) RETURN n;

rでリレーション全検索かな?

MATCH でノードを指定して検索する。このとき、ノードの属性も指定して検索できる。,で複数ノードを指定できる。
例:すべて検索

MATCH (n)
RETURN n

WHERE で条件指定できる。MATCH と組み合わせて検索することができる。
条件はANDで複数指定することができる。このあたりはSQLと同じかな。

RETURN でノードを取得することができる。Web画面からサイファー実行し、取得したノードはWeb画面でグラフ表示することができる。

最短経路の検索

MATCH (p1:Point{name:"p1"}), (p5:Point{name:"p5"}), g = shortestPath((p1)-[:Route*]-(p5))
RETURN g;

実際には階層を絞る。冗長になるので。

g = shortestPath((p1)-[:Route*..5]-(p5))

所要時間が最短となるp1からp5への経路

MATCH
g = (:Point{name:"p1"})-[:Route*]-(:Point{name:"p5"})
RETURN g,
REDUCE(weight=0, r in RELATIONSHIPS(g) | weight+r.weight) AS score
ORDER BY score ASC
LIMIT 1;

正規表現で検索することができる

MATCH (user:User) WHERE user.name =~ ".*ice.*" RETURN user;

識別子userノードの範囲内検索

MATCH (user:User) WHERE user.age > 20 AND user.age < 30 RETURN user;

識別子userノードを起点として、友達の友達までを検索

MATCH (user:User{name: "Alice"})-[:FRIEND*1..2]->(to) RETURN to;

識別子userノードを起点として、友達の友達だけを検索

MATCH (user:User{name: "Alice"})-[:FRIEND*2]->(to) RETURN to;

識別子userノードを起点として、関連のある1~3層まで検索

MATCH (user:User{name: "Alice"})-[*1..3]->(to) RETURN to;

識別子userノードを起点として、関連のある全てを検索

MATCH (user:User{name: "Alice"})-[*]->(to) RETURN to;

ノードのみ検索

MATCH (n:User {name:"Alice"}) RETURN n;

ラベルの記述が無くとも、識別子だけで検索できる

MATCH (SAMPLE1), (SAMPLE2) RETURN SAMPLE1,SAMPLE2;

SAMPLEノードに関連するノード・リレーションを検索

MATCH (from)-[:FLONT*]->(SAMPLE {name: "SAMPLE"})-[:FLONT*]->(to)
RETURN from,to,SAMPLE;

from と to が予約語のようで、nだけでは予約語が足りないときに使用するといい。

更新(Update)

SETで更新することが出来る。SETを使う際には、対象を指定するために検索する。

MATCH (n { name: 'Andy' })
SET n.surname = 'Taylor'
RETURN n.name, n.surname

nを識別子にしてもいい、条件が絞れる。さらに絞るなら MATCH (user: USER { name: ‘Andy’ }) のように識別子:ラベルを記載する。ここは検索と同様。WHEREも使用可能。

削除(Delete)

DELETE でノード、リレーションを削除することができる。RETURN の場所にDELETE と記載する。
例:すべて削除

MATCH (n) DETACH DELETE n;

※NodeをDELETEする場合、そのNodeにつながるRelationshipは事前に削除しておく必要がある
DETACH DELETEは、NodeにRelationshipが残っていても、Relationshipを含め削除してくれる

REMOVE で属性の削除
例:

MATCH (n:Person {name:"香川"})
REMOVE n.from

SET でノード情報を更新できる。MATCH でノードを指定して繋げてSET で更新する。変更する属性が無ければ追加する。
例:

MATCH (n:Person {name:"香川"})
SET n.from = "神戸"

孤立ノードの削除

MATCH (n) WHERE NOT (n)-() DELETE n

全ノードをリレーションを削除

MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n, r;

方向無視で検索するには、方向<>をつけないでMATCHを書く。

CRUDする方法が分かったらSpring Bootから操作してみましょう。

Spring Boot で Neo4j へのアクセス、データ取得(組込みNeo4jドライバーを使用)
Spring Boot で Neo4j からデータ取得して画面表示させてみました。 Neo4j への接続には、組込みNeo4jドライバ...

参考

Neo4j Cypherチートシート – neo4j

逆引きCypher – gist