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
關系語法
? 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]]
- 參數:
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