Cypher 概述與基本語法

1,Cypher概述

Cypher是一種聲明式圖數據庫查詢語言,它具有豐富的表現力,能高效地查詢和更新圖數據。

Cypher借鑒了SQL語言的結構——查詢可由各種各樣的語句組合。

例如,下面是查找名為'John'的人和他的朋友的朋友。

MATCH (john {name: 'John'})-[:friend]->()-[:friend]->(fof)
RETURN john.name, fof.name

? 接下來在語句中添加一些過濾。給定一個用戶名列表,找到名字在列表中的所有節點。匹配他們的朋友,僅返回他們朋友的name屬性以'S'開頭的用戶。

MATCH (user)-[:friend]->(follower)
WHERE user.name IN ['Joe', 'John', 'Sara', 'Maria', 'Steve'] AND follower.name =~ 'S.*'
RETURN user.name, follower.name

模式(Patterns)

? Neo4j圖由節點和關系構成。節點可能還有標簽和屬性,關系可能還有類型和屬性。節點和關系都是簡單的低層次的構建塊。單個節點或者關系只能編碼很少的信息,但模式可以將很多節點和關系編碼為任意復雜的想法。

? Cypher查詢語言很依賴于模式。只包含一個關系的簡單模式連接了一對節點。例如,一個人LIVES_IN在某個城市或者某個城市PART_OF一個國家。使用了多個關系的復雜模式能夠表達任意復雜的概念,可以支持各種有趣的使用場景。例如,下面的Cypher代碼將兩個簡單的模式連接在一起:

(:Person)-[:LIVES_IN]->(:City)-[:PART_OF]->(:Country)  

? 像關系數據庫中的SQL一樣,Cypher是一種文本的聲明式查詢語言。它使用ASCII art的形式來表達基于圖的模式。采用類似SQL的語句,如MATCH,WHERE和DELETE,來組合這些模式以表達所預期的操作。


節點語法

? Cypher采用一對圓括號來表示節點。如:(), (foo)。下面是一些常見的節點表示法:

()
(matrix)
(:Movie)
(matrix:Movie)
(matrix:Movie {title: "The Matrix"})
(matrix:Movie {title: "The Matrix", released: 1997})
match (matrix:Movie {title: "The Matrix"}) return matrix
節點.png

關系語法

? Cypher使用一對短橫線(即“--”)表示:一個無方向關系。有方向的關系在其中一端加上一個箭頭(即“<--”或“-->”)。方括號表達式[…]可用于添加關系信息。里面可以包含變量、屬性和或者類型信息。關系的常見表達方式如下:

--
-->
-[role]->
-[:ACTED_IN]->
-[role:ACTED_IN]->
-[role:ACTED_IN {roles: ["Neo"]}]->
# 找出"Hugo Weaving"參演的電影
match (n:Person{name:"Hugo Weaving"})-[r:ACTED_IN]->(m) return n,r,m

關系.png

模式語法

將節點和關系的語法組合在一起可以表達模式。

(keanu:Person {name: "Keanu Reeves"})-[role:ACTED_IN {roles: ["Neo"]}]->(matrix:Movie {title: "The Matrix"})

事務

? 任何更新圖的查詢都運行在一個事務中。一個更新查詢要么全部成功,要么全部失敗。Cypher或者創建一個新的事務,或者運行在一個已有的事務中:

  • 如果運行上下文中沒有事務,Cypher將創建一個,一旦查詢完成就提交該事務。
  • 如果運行上下文中已有事務,查詢就會運行在該事務中。直到該事務成功地提交之后,數據才會持久化到磁盤中去。

兼容性

? Cypher不是一成不變的語言。新版本引入了很多新的功能,一些舊的功能可能會被移除。如果需要,舊版本依然可以訪問到。這里有兩種方式在查詢中選擇使用哪個版本:

  • 為所有查詢設置版本:可以通過neo4j.conf中cypher.default_language_version參數來配置Neo4j數據庫使用哪個版本的Cypher語言。
  • 在查詢中指定版本:簡單地在查詢開始的時候寫上版本,如Cypher 2.3。

2,cypher基本語法

類型

Cypher處理的所有值都有一個特定的類型,它支持如下類型:

  • 數值型
  • 字符串
  • 布爾型
  • 節點
  • 關系
  • 路徑
  • 映射(Map)
  • 列表(List)

表達式

  • Cypher中的表達式如下:
  • 十進制(整型和雙精度型)的字面值:13, -4000, 3.14, 6.022E23
  • 十六進制整型字面值(以0x開頭):0x13zf, 0xFC3A9, -0x66eff
  • 八進制整型字面值(以0開頭):01372, 02127, -05671
  • 字符串字面值:'Hello', "World"
  • 布爾字面值:true, false, TRUE, FALSE
  • 變量:n, x, rel, myFancyVariable
  • 屬性:n.prop, x.prop, rel.thisProperty
  • 動態屬性:n["prop"], rel[n.city + n.zip], map[coll[0]]
  • 參數:param,0
  • 表達式列表:['a', 'b'], [1, 2, 3], ['a', 2, n.property, $param], [ ]
  • 函數調用:length(p), max(p)
  • 聚合函數:avg(x.prop), count()
  • 路徑-模式:(a)-->()<--(b)
  • 算式:1 + 2 >3 and 3 < 4.
  • 返回true或者false的斷言表達式:a.prop = 'Hello', length(p) >10, exists(a.name)
  • 正則表達式:a.name =~ 'Tob.*'
  • 大小寫敏感的字符串匹配表達式:a.surname STARTS WITH 'Sven', a.surname ENDS WITH 'son'
  • CASE表達式

轉義字符

Cypher中的字符串可以包含如下轉義字符:

字符 含義
\t 制表符
\b 退格
\n 換行
\r 回車
\f 換頁
' 單引號
" 雙引號
\ 反斜杠
\uxxxx Unicode UTF-16編碼點(4位的十六進制數字必須跟在\u后面)
\Uxxxxxxxx Unicode UTF-32 編碼點(8位的十六進制數字必須跟在\U后面)

Case表達式

? 計算表達式的值,然后依次與WHEN語句中的表達式進行比較,直到匹配上為止。如果未匹配上,則ELSE中的表達式將作為結果。如果ELSE語句不存在,那么將返回null。

語法:

CASE test.value
WHEN value1 THEN result1
WHEN value2 THEN result2
[WHEN ...]
[ELSE default]
END AS result

例子:

MATCH (p:Person)
return
CASE p.born
WHEN 1997 THEN 1
WHEN '1942' THEN 2
ELSE 3 END AS result

變量

? 當需要引用模式(pattern)或者查詢的某一部分的時候,可以對其進行命名。針對不同部分的這些命名被稱為變量。例如:

# 這里的n和b和r就是變量。
MATCH (n)-[r]->(b)
RETURN b 

參數

? Cypher支持帶參數的查詢。這意味著開發人員不是必須用字符串來構建查詢。此外,這也讓執行計劃的緩存更容易。

? 參數能夠用于WHERE語句中的字面值和表達式,START語句中的索引值,索引查詢以及節點和關系的id。參數不能用于屬性名、關系類型和標簽,因為這些模式(pattern)將作為查詢結構的一部分被編譯進查詢計劃。

? 合法的參數名是字母,數字以及兩者的組合。下面是一個使用參數的完整例子。參數以JSON格式提供。具體如何提交它們取決于所使用驅動程序。

{
"name" : "Johan"
}
match (n:Person) where n.name=$name return n

運算符

數學運算符

包括+,-,*,/ 和%,^。

比較運算符

包括=,<>,<,>,<=,>=,IS NULL和IS NOT NULL。

布爾運算符

包括AND,OR,XOR和NOT。

字符串運算符

連接字符串的運算符為+。

正則表達式的匹配運算符為=~。

列表運算符

列表的連接也可以通過+運算符。

可以用IN來檢查列表中是否存在某個元素。

值的相等與比較

Cypher支持使用=和<>來比較兩個值的相等/不相等關系。同類型的值只有它們是同一個值的時候才相等,如3 = 3和"x" <> "xy"。

值的排序與比較

比較運算符<=,<(升序)和>=,>(降序)可以用于值排序的比較。如下所示:

  • 數字型值的排序比較采用數字順序
  • java.lang.Double.NaN大于所有值
  • 字符串排序的比較采用字典順序。如"x" < "xy"
  • 布爾值的排序遵循false < true
  • 當有個參數為null的時候,比較結果為null。如null < 3的結果為null
  • 將其他類型的值相互比較進行排序將報錯
鏈式比較運算

比較運算可以被任意地鏈在一起。如x < y <= z等價于x < y AND y <= z。如:

MATCH (n) WHERE 21 < n.age <= 30 RETURN n

等價于:

MATCH (n) WHERE 21 < n.age AND n.age <= 30 RETURN n
注釋

Cypher語言的注釋類似其他語言,用雙斜線//來注釋行。例如:

MATCH (n) RETURN n //這是行末尾注釋
MATCH (n)
//這是整行注釋
RETURN n
MATCH (n) WHERE n.property = '//這不是注釋' RETURN n 

模式(Patterns)

? 使用模式可以描述你期望看到的數據的形狀。例如,在MATCH、CREATE、DELETE等語句中,當用模式描述一個形狀的時候,Cypher將按照模式來獲取相應的數據。

? 模式描述數據的形式很類似在白板上畫出圖的形狀。通常用圓圈來表達節點,使用箭頭來表達關系。節點模式

? 模式能表達的最簡單的形狀就是節點。節點使用一對圓括號表示,然后中間含一個名字。例如:

(a)
//這個模式描述了一個節點,其名稱使用變量a表示。

關聯節點的模式

模式可以描述多個節點及其之間的關系。Cypher使用箭頭來表達兩個節點之間的關系。例如:

(a)-->(b)
(a)-->(b)<--(c)
(a)-->()<--(c)

標簽

模式除了可以描述節點之外,還可以用來描述標簽。例如:

(a:User)-->(b)
(a:User:Admin)-->(b)

指定屬性

屬性在模式中使用鍵值對的映射結構來表達,然后用大括號包起來。例如,一個有兩個屬性的節點如下所示:

(a {name: 'Andres', sport: 'Brazilian Ju-Jitsu'}) 
// 關系中的屬性
(a)-[{blocked: false}]->(b)

描述關系

? 如前面的例子所示,可以用箭頭簡單地描述兩個節點之間的關系。它描述了關系的存在性和方向性。但如果不關心關系的方向,則箭頭的頭部可以省略。例如:

(a)--(b)

? 與節點類似,如果后續需要引用到該關系,則可以給關系賦一個變量名。變量名需要用方括號括起來,放在箭頭的短橫線中間,如下所示:

(a)-[r]->(b)

就像節點有標簽一樣,關系可以有類型(type)。給關系指定類型,如下所示:

(a)-[r:REL_TYPE]->(b)

? 不像節點可以有多個標簽,關系只能有一個類型。但如果所描述的關系可以是一個類型集中的任意一種類型,可以將這些類型都列入到模式中,它們之間以豎線“|”分割。如:

(a)-[r:TYPE1|TYPE2]->(b)

? 注意:這種模式僅適用于描述已經存在的數據(如在MATCH語句中),而在CREATE或者MERGE語句中是不允許的,因為一個關系不能創建多個類型。

? 與使用一串節點和關系來描述一個長路徑的模式不同,很多關系(以及中間的節點)可以采用指定關系的長度的模式來描述。例如:

(a)-[*2]->(b)

? 它描述了一張三個節點和兩個關系的圖。這些節點和關系都在同一條路徑中(路徑的長度為2)。它等同于:

(a)-->()-->(b)

? 關系的長度也可以指定一個范圍,這被稱為可變長度的關系。例如:

(a)-[*3..5]->(b)

? 長度的邊界也是可以省略的,如描述一個路徑長度大于等于3的路徑:

(a)-[*3..]->(b) 

? 路徑長度小于等于5的路徑,如:

(a)-[*..5]->(b) 

? 兩個邊界都可以省略,這允許任意長度的路徑,如:

(a)-[*]->(b)

列表

Cypher對列表(list)有很好的支持。可以使用方括號和一組以逗號分割的元素來創建一個列表。如:

RETURN [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] AS list 
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。