cypher是neo4j官網提供的聲明式查詢語言,很是強大,用它能夠完成任意的圖譜裏面的查詢過濾,咱們知識圖譜的一期項目 基本開發完畢,後面會陸續總結學習一下neo4j相關的知識。今天接着上篇文章來看下neo4j的cpyher查詢的一些基本概念和語法。node
在cypher裏面經過用一對小括號()表示一個節點,它在cypher裏面查詢形式以下:web
1,() 表明匹配任意一個節點sql
2, (node1) 表明匹配任意一個節點,並給它起了一個別名json
3, (:Lable) 表明查詢一個類型的數據app
4, (person:Lable) 表明查詢一個類型的數據,並給它起了一個別名less
5, (person:Lable {name:"小王"}) 查詢某個類型下,節點屬性知足某個值的數據ide
6, (person:Lable {name:"小王",age:23}) 節點的屬性能夠同時存在多個,是一個AND的關係模塊化
關係用一對-組成,關係分有方向的進和出,若是是無方向就是進和出都查詢函數
1,--> 指向一個節點oop
2,-[role]-> 給關係加個別名
3,-[:acted_in]-> 訪問某一類關係
4,-[role:acted_in]-> 訪問某一類關係,並加了別名
5,-[role:acted_in {roles:["neo","hadoop"]}]->
訪問某一類關係下的某個屬性的關係的數據
模式語法是節點和關係查詢語法的結合,經過模式語法咱們能夠進行咱們想要的任意複雜的查詢
(p1: Person:Actor {name:"tom"})-[role:acted_in {roles:["neo","actor"]}]-(m1:Movie {title:"water"})
爲了增長模塊化和減小重複,cypher容許把模式的結果指定在一個變量或者別名中,方便後續使用或操做
path = (: Person)-[:ACTED_IN]->(:Movie)
path是結果集的抽象封裝,有多個函數能夠直接從path裏面提取數據如:
nodes(path):提取全部的節點
rels(path): 提取全部的關係 和relationships(path)相等
length(path): 獲取路徑長度
cypher語句也是由多個關鍵詞組成,像SQL的
select name, count(*) from talbe where age=24 group by name having count(*) >2 order by count(*) desc
多個關鍵字組成的語法,cypher也很是相似,每一個關鍵詞會執行一個特定的task來處理數據
match: 查詢的主要關鍵詞
create: 相似sql裏面的insert
filter,project,sort,page等都有對應的功能語句
經過組合上面的一些語句,咱們能夠寫出很是強大複雜的語法,來查詢咱們想要檢索的內容,cypher會 自動解析語法並優化執行。
一些實際的用法例子:
create (:Movie {title:"驢得水",released:2016}) return p;
執行成功,在neo4j的web頁面咱們能看到下面的信息
+-------------------+| No data returned. | +-------------------+Nodes created: 1 Properties set: 2 Labels added: 1
固然cypher也能夠一次建立多個數據,並同時添加關係
match (p: Person) return p; 查詢Person類型的全部數據
match (p: Person {name:"sun"}) return p; 查詢名字等於sun的人
match( p1: Person {name:"sun"} )-[rel:friend]->(p2) return p2.name , p2.age 查詢sun的朋友的名字和年齡
match (old) ... create (new) create (old)-[rel:dr]->(new) return new 對已經存在的節點和新建的節點創建關係
merge 語法能夠對已經存在的節點不作改變,對變化的部分會合並
MERGE (m:Movie { title:"Cloud Atlas" })ON CREATE SET m.released = 2012RETURN m
merge .... on create set ... return 語法支持合併更新
cypher過濾也是用的和SQL同樣的關鍵詞where
match (p1: Person) where p1.name="sun" return p1;
等同下面的
match (p1: Person {name:"sun"}) return p1
注意where條件裏面支持 and , or ,xor,not等boolean運算符,在json串裏面都是and
除此以外,where裏面查詢還支持正則查詢
match (p1: Person)-[r:friend]->(p2: Person) where p1.name=~"K.+" or p2.age=24 or "neo" in r.rels return p1,r,p2
關係過濾匹配使用not
MATCH (p:Person)-[:ACTED_IN]->(m)WHERE NOT (p)-[:DIRECTED]->()RETURN p,m
MATCH (p:Person)RETURN p, p.name AS name, upper(p.name), coalesce(p.nickname,"n/a") AS nickname, { name: p.name, label:head(labels(p))} AS person
結果集返回作去重
match (n) return distinct n.name;
cypher支持count,sum,avg,min,max
match (: Person) return count(*)
聚合的時候null會被跳過 count 語法 支持 count( distinct role )
MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie)<-[:DIRECTED]-(director:Person)RETURN actor,director,count(*) AS collaborations
MATCH (a:Person)-[:ACTED_IN]->(m:Movie)RETURN a,count(*) AS appearancesORDER BY appearances DESC SKIP 3 LIMIT 10;
MATCH (m:Movie)<-[:ACTED_IN]-(a:Person) RETURN m.title AS movie, collect(a.name) AS cast, count(*) AS actors
支持兩個查詢結構集同樣的結果合併
MATCH (actor:Person)-[r:ACTED_IN]->(movie:Movie) RETURN actor.name AS name, type(r) AS acted_in, movie.title AS title UNION (ALL) MATCH (director:Person)-[r:DIRECTED]->(movie:Movie) RETURN director.name AS name, type(r) AS acted_in, movie.title AS title
with語句給cypher提供了強大的pipeline能力,能夠一個或者query的輸出,或者下一個query的輸入 和return語句很是相似,惟一不一樣的是,with的每個結果,必須使用別名標識。
經過這個功能,咱們能夠垂手可得的作到在查詢結果裏面在繼續嵌套查詢。
MATCH (person:Person)-[:ACTED_IN]->(m:Movie) WITH person, count(*) AS appearances, collect(m.title) AS movies WHERE appearances > 1RETURN person.name, appearances, movies
注意在SQL裏面,咱們想過濾聚合結果,須要使用having語句可是在cypher裏面咱們能夠配合with語句使用 where關鍵詞來完成過濾
惟一約束(使用merge來實現) CREATE CONSTRAINT ON (movie:Movie) ASSERT movie.title IS UNIQUE
添加索引(在圖譜遍歷時,快速找到開始節點),大幅提升查詢遍歷性能 CREATE INDEX ON :Actor(name)
添加測試數據:
CREATE (actor:Actor { name:"Tom Hanks" }),(movie:Movie { title:'Sleepless IN Seattle' }), (actor)-[:ACTED_IN]->(movie);
使用索引查詢:
MATCH (actor:Actor { name: "Tom Hanks" })RETURN actor;