Cypher筆記(一)
更詳細的內容請閱讀《neo4j權威指南》
運算符
- 數學運算符:+、-、*、/、%、^
- 比較運算符:=、<>、<、>、<=、>=、IS NULL、IS NOT NULL
- 布爾運算符:AND、OR、XOR、NOT
- 字符串運算符:+、=~
- 列表運算符:+、IN
語句
- 讀語句:MATCH、OPTIONAL MATCH、WHERE、START、Aggregation、LOAD CSV
- 寫語句:CREATE、MERGE、SET、DELETE、REMOVE、FOREACH、CREATE UNIQUE
- 通用語句:RETURN、ORDER BY、LIMIT、SKIP、WITH、UNWIND、UNION、CALL
- 字符串匹配:STARTS WITH、ENDS WITH、CONTAINS
MATCH
MATCH是模式描述的一部分,匹配的時候就會考慮到WHERE語句中的斷言,而不是匹配之後。
OPTIONAL MATCH
用於搜索模式中描述的匹配項,對於找不到的項用null代替。
WHERE
在WITH和START中用於過濾結果,在MATCH和OPTIONAL MATCH中爲模式增加約束,而不能看作匹配完成後的結果過濾
START
通過遺留索引查找開始點
START n = node:Pig(name = 'A') RETURN n
START n = node:Pig('name:A') RETURN n
START r = relationship:Own(name = 'Andres') RETURN r
Aggregation
- count:count(*)用於計算匹配的行數,count(<expression>)用於計算<expression>中的非空值的數量
- sum:計算所有值之和,空值會被丟棄
- avg:計算數值列平均值
- percentileDisc:計算給定值在一個組中的百分位,取值0.0到1.0。它使用舍入法返回最接近百分位的值
- percentileCont:計算給定值在一個組中的百分位,取值0.0到1.0。採用線性插值的方法,在兩個值之間計算一個加權平均數
- stdev:計算給定值在一個組中的標準偏差,採用標準的two-pass方法,以N-1作爲分母,當以部分樣本作爲無偏估計時應使用stdev;當計算整個樣本的標準偏差時應使用stdevp
- stdevp:計算給定值在一個組中的標準偏差
- max
- min
- collect:將所有值收集起來放入一個列表,空值會被忽略
- distinct:去掉重複值
MATCH (n { name: 'A' })-->(x) RETURN n, count(*) // 返回了開始節點和與之關聯的節點數量
LOAD CSV
用於從CSV文件中導入數據
- CSV文件的URL可以由FROM後面緊跟的任意表達式來指定
- 需要使用AS來爲CSV數據指定一個常量
- LOAD CSV支持gzip、Deflate和ZIP壓縮的資源
- CSV文件可以存在數據庫服務器上,通過file:///URL來訪問。LOAD CSV也支持通過HTTPS、HTTP、FTP來訪問CSV文件
- LOAD CSV支持HTTP重定向,但基於安全考慮重定向時不能該表協議類型,比如衝HTTPS到HTTP
MERGE
確保圖數據庫中存在某個特定的模式,如果不存在就創建它,如果存在則合併屬性(邏輯或)
MATCH (person:Person) MERGE (city:City { name: person.bornIn }) RETURN city
MERGE (keanu:Person { name: 'Keanu Reeves' })
ON CREATE SET keanu.created = timestamp()
RETURN keanu.name, keanu.created
MERGE (person:Person)
ON MATCH SET person.found = True
RETURN person.name, person.found
MERGE (keanu:Person { name: 'Keanu Reeves' })
ON CREATE SET keanu.created = timestamp()
ON MATCH SET keanu.lastSeen = timestamp(), keanu.found = True
RETURN keanu.name, keanu.created, keanu.lastSeen
// 如果節點不存在則設置created屬性,否則設置lastSeen和found屬性
CREATE CONSTRAINT ON (n:Person) ASSERT n.name IS UNIQUE
CREATE CONSTRAINT ON (n:Person) ASSERT n.role IS UNIQUE
MERGE (michael:Person{ name: 'Michael Douglas', role: 'Grodon Gekko' }) RETURN michael
SET
用於更新節點的標籤以及節點和關係的屬性
MATCH (n { name: 'Andres' }) SET n.name = NULL RETURN n // 刪除節點屬性
MATCH (at { name: 'Andres' }), (pn { name: 'Peter' }) SET at = pn RETURN at, pn // 複製屬性
MATCH (peter { name: 'Peter' }) SET peter += { hungry: TRUE, position: 'Entrepreneur' } RETURN peter
MATCH (n { name: 'Stefan' }) SET n:German:Bossman RETURN n
DELETE
刪除圖元素(關係、節點和路徑)。注意不能只刪除節點,而不刪除與之關聯的關係,要麼顯示地刪除對應的關係,要麼使用DETACH DELETE
MATCH (n { name: 'Andres' }) DETACH DELETE n
REMOVE
用於刪除圖元素的屬性和標籤
MATCH (n { name: 'Andres' }) REMOVE n.age, n:German:Swedish RETURN n
FOREACH
用於更新列表中的數據,或者來自路徑的組建,或者來自聚合的結果
MATCH p = (begin)-[*]-(END)
WHERE begin.name = 'A' AND END.name = 'D'
FOREACH (n IN nodes(p) | SET n.marked = TRUE )
MATCH (a:Person {name: 'A'})
FOREACH (name IN ['Mike', 'Carl', 'Bruce'] | CREATE (a)-[:FRIEND]->(:Person {name: 'name'}))
CREATE UNIQUE
儘可能的匹配,然後創建爲匹配到的。MERGE並不能很強的保證關係的唯一性。CREATE UNIQUE不回去修改現有圖。
MATCH (root { name: 'root' }) CREATE UNIQUE (root)-[:LOVES]-(someone:German { alone: false }) RETURN someone
// 原本root節點沒有與任何節點有LOVES關係,因此創建了一個新的節點與root建立LOVES關係
ORDER BY
緊跟RETURN和WITH,指定了輸出結果如何排序。升序排列時空值總在結果末尾,降序排列相反。
MATCH (n) RETURN ORDER BY n.name, n.age DESC
// 多屬性排序,先根據第一個屬性排序,值相同時再檢查第二個屬性,依次類推
MATCH (n) RETURN n ORDER BY n.name SKIP toInt(3 * rand()) + 1 LIMIT toInt(3 * rand()) + 1
WITH
將分段的查詢部分連接在一起,查詢結果從一部分以管道的形式傳遞到另一部分作爲開始點。操作可以改變結果的形式和數量。當寫部分基於讀部分的結果時,兩者之間的轉換必須使用WITH。
MATCH (david { name: 'David' })--(otherPerson)-->()
WITH otherPerson, count(*) AS foaf
WHERE foaf > 1 RETURN otherPerson
MATCH (n) WITH n ORDER BY n.name DESC LIMIT 3 RETURN collect(n.name)
MATCH (n { name: 'Anders' })--(m)
WITH m ORDER BY m.name DESC LIMIT 1
MATCH (m)--(o) RETURN o.name
UNWIND
將一個列表展開爲一個行的序列
UNWIND [1, 2, 3] AS x RETURN x
WITH [1, 1, 2, 2] AS coll UNWIND coll AS x WITH DISTINCT x RETURN collect(x) AS set
UNION
將多個查詢結果組合起來
MATCH (n:Actor) RETURN n.name AS name UNION ALL MATCH (n:Movie) RETURN n.title AS name
// UNION ALL將兩個查詢的結果組合在一起,結果包含重複行
MATCH (n:Actor) RETURN n.name AS name UNION MATCH (n:Movie) RETURN n.title AS name
// 結果無重複值
CALL
用於調用數據庫中的過程。使用CALL語句調用過程時需要指定所需要的參數,可以通過在過程名的後面使用都好分隔的列表來顯式地指定,也可以用查詢參數來作爲過程調用的實參,後者僅適用於在單獨的過程調用中作爲參數,即整個查詢語句只包含一個單一的CALL調用。大多數過程返回固定列的記錄流。YIELD子句用於顯示地選擇返回結果集中的哪些部分並綁定到一個變量以供後續的查詢引用。在一個更大的查詢內部,過程調用返回的結果可以顯示地使用YIELD引入一個WHERE子句來過濾結果。
CALL db.labels
CALL `db`.`labels`
CALL org.neo4j.procedure.example.addNodeToIndex('users', 0, 'name')
CALL org.neo4j.procedure.example.addNodeToIndex('users', $node, 'name')
CALL db.labels() YIELD result AS label WHERE label CONTAINS 'User' RETURN count(label) AS numLabels
函數
- 斷言函數
- all:判斷是否一個斷言適用於列表中的所有元素
- all(variable IN list WHERE predicate)
- any:判斷是否一個斷言至少適用於列表中的一個元素
- any(variable IN list WHERE predicate)
- none:如果斷言不適用於列表中的任何元素,則返回true
- none(variable IN list WHERE predicate)
- single:如果斷言剛好只適用於列表中的一個元素,返回true
- single(variable IN list WHERE predicate)
- exists:如果數據庫中存在該模式或者節點中存在該屬性時,返回true
- exists(pattern-or-property)
- all:判斷是否一個斷言適用於列表中的所有元素
- 標量函數:返回一個單值
- size:返回表中元素的個數
- size(list)
- size:模式表達式的size,計算的時結果集元素的個數,而不是表達式本身的長度
- size(pattern expression)
- length:返回路徑的長度
- length(path)
- length:返回字符串的長度
- length(string)
- type:返回字符串代表的關係類型
- type(relationship)
- id:返回關係或者節點的id
- id(property-container)
- coalesce:返回表達式列表中第一個非空的值,如果所有實參都爲空,則返回null
- coalesce(expression[, expression]*)
- head:返回列表中的第一個元素
- head(expression)
- last:返回列表中的最後一個元素
- last(expression)
- timestamp:返回當前時間與1970年1月1日午夜之間的差值,單位毫秒
- timestamp()
- startNode:返回一個關係的開始節點
- startNode(relationship)
- endNode:返回一個關係的結束節點
- endNode(relationship)
- properties:將實參轉爲屬性值的map。如果實參是一個節點或者關係,返回的就是節點或關係的屬性的map,如果實參已經是一個map,那麼原樣返回
- properties(expression)
- toInt、toFloat
- size:返回表中元素的個數
- 列表函數
- nodes:返回一條路徑中的所有節點
- relationships:返回一條路徑中的所有關係
- labels:以字符串列表的形式返回一個節點的所有標籤
- keys:以字符串列表的形式返回一個節點、關係或者map的所有屬性的名稱
- extract:從節點或者關係列表中返回單個屬性或者某個函數的值。它將遍歷整個列表,針對列表中的每一個元素運行一個表達式,然後以列表的形式返回這些結果。它的工作方式類型類似於Lisp和Scala等函數式語言中的map方法
- extract(variable IN list | expression)
- filter:返回列表中滿足斷言要求的所有元素
- filter(variable IN list WHERE predicate)
- tail:返回列表中除了首元素之外的所有元素
- range:返回某個範圍內的數值,值默認步長爲1,範圍包含起始邊界
- range(start, end[, step])
- reduce:對列表中的每一個元素執行一個表達式,將表達式的結果存入一個累加器
- reduce(accumulator = initial, variable IN list | expression)
- 數學函數
- abs:絕對值
- ceil:返回大於等於實參的最小整數,上取整
- floor:返回小於等於實參的最大整數,下取整
- round:返回距離表達式值最近的整數,四捨五入
- sign:返回表達式正負號
- rand:返回(0, 1)之間一個隨機數,返回的數值在整個區間均勻分佈
- log:自然對數
- log10:常用對數
- exp:返回e^n
- e:返回自然對數的底
- sqrt:平方根
- sin、cos、tan、cot、asin、acos、atan、atan2
- pi:常數pi
- degrees:弧度轉度
- radians:度轉弧度
- haversin:半正矢
- 字符串函數
- replace:replace(original, search, replace)
- substring:substring(original, start[, length])
- left:left(original, length)
- right:right(original, right)
- ltrim、rltrim、trim:移除空白字符
- lower、upper
- split:split(original, splitPattern)
- reverse
- toString
自定義函數
自定義函數用Java語言編寫,可部署到數據庫中,調用方式和其他Cypher函數一樣,舉個例子:
MATCH (n:Member) RETURN org.neo4j.function.example.join(collect(n.name))
編寫自定義函數類似於過程的創建,但它採用@UserFunction
註解,並且只返回一個單值。有效的輸出類型包括long、Long、double、Double、boolean、Boolean、String、Node、Relationship、Path、Map<String, Object>、List<T>,舉個例子:package example; import org.neo4j.procedure.Name; import org.neo4j.procedure.Procedure; import org.neo4j.procedure.UserFunction; public class Join { @UserFunction @Description("example.join(['s1', 's2', ...], delimiter) - join the given strings with the given delimiter.") public String join( @Name("strings") List<String> strings, @Name(value = "delimiter", defaultValue = ",") String delimiter) { if (strings == null || delimiter == null) return null; else return Strings.join(delimiter, strings); } } >
其他實例
MATCH (john {name: 'John'})-[:friend]->(fof)
RETURN john.name, fof.name
MATCH (user)-[:friend]->(follower)
WHERE user.name IN ['Joe', 'John', 'Sara', 'Maria', 'Steve'] AND follower.name = ~'S.*'
RETURN user.name, follower.name
MATCH (n {name: 'John'})-[:FRIEND]-(friend)
WITH n, count(friend) AS friendsCount
WHERE friendsCount > 3
RETURN n, friendsCount
MATCH (n {name: 'John'})-[:FRIEND]-(friend)
WITH n, count(friend) AS friendsCount
SET n.friendsCount = friendsCount
RETURN n.friendsCount
CREATE (adam:User{name: 'Adam'}), (pernilla:User{name: 'Pernilla'}), (david:User{name: 'David'}),
(adam)-[:FRIEND]->(pernilla), (pernilla)-[:FRIEND]->(david)
MATCH (user: User{name: 'Adam'})-[r1: FRIEND]-()-[r2:FRIEND]-(friend_of_a_friend)
RETURN friend_of_a_friend.name AS fofName
MATCH (user:User{name: 'Adam'})-[r1:FRIEND]-(friend), (friend)-[r2:FRIEND]-(friend_of_a_friend)
RETURN friend_of_a_friend.name AS fofName
MATCH (user:User{name: 'Adam'})-[r1:FRIEND]-(friend)
MATCH (friend)-[r2:FRIEND]-(friend_of_a_friend)
RETURN friend_of_a_friend.name AS fofName
CYPHER 2.3
START n = node:nodes(name = 'A')
RETURN n
MATCH (n)
RETURN
CASE n.eyes
WHEN 'blue'
THEN 1
WHEN 'brown'
THEN 2
ELSE 3 END AS result
MATCH (a) WHERE a.surname STARTS WITH 'Sven' AND a.prename ENDS WITH 'PY' RETURN a
MATCH (n) WHERE n.name = ~'.*h.*' AND n.address = ~'Sweden\\/Malmo' RETURN n // 注意反斜槓也要轉義
MATCH (n) RETURN n.name SKIP 1 LIMIT 3
MATCH (n) WHERE id(n) = 10 RETURN n.name
MATCH (n) WHERE id(n) IN [1, 3, 54] RETURN n.name
MATCH (n) WHERE 21 < n.age < 30 RETURN n
MATCH (n) RETURN n // 這是註釋
(a)--(b)
(a)-->(b)<--(c)
(a)-[{blocked: false}]->(b)
(a)-[r:TYPE1 | TYPE2]->(b)
(a)-[*2]->(b)
(a)-[*3..]->(b)
(a)-[*3..5]->(b)
MATCH (me)-[:KNOWS*1..2]-(remote_friend)
WHERE me.name = 'Filipa'
RETURN remote_friend.name
p = (a)-[*3..5]->(b)
RETURN [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] AS list
RETURN range(0, 10)[3]
RETURN range(0, 10)[-3]
RETURN range(0, 10)[0..3]
RETURN range(0, 10[0..-5]
RETURN size(range(0, 10))
RETURN [x IN range(0, 10) WHERE x % 2 = 0 | x^3] AS result
RETURN [x IN range(0, 10) | x^3] AS result // ^是數學運算符
MATCH (a:Person{name: 'Charile Sheen'})
RETURN [(a)-->(b) WHERE b:Movie | b.year] AS years
RETURN {key: 'Value', listKey: [{ inner: 'Map1' }, { inner: 'Map2'}]}
MATCH (actor:Person {name: 'Charlie Sheen'})-[:ACTED_IN]->(movie:Movie)
RETURN actor { .name, .realName, movies: collect(movie { .title, .year })}
MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie)
WITH actor, count(movie) AS nrOfMovies
RETURN actor { .name, nrOfMovies }
MATCH (actor:Person{ name: 'Charlie Sheen' })
RETURN actor { .*, .age }
MATCH (wallstreet { title: 'Wall Street' })<-[:ACTED_IN | :DIRECTED]-(person)
RETURN person.name
MATCH (n { name: 'Rob Reiner'})-[r:`TYPE WITH SPACE`]->() RETURN type(r)
MATCH (martin { name: 'Charlie Sheen'})-[:ACTED_IN*1..3]-(movie:Movie) RETURN movie.title
// 結果:['Wall Street', 'The American President', 'The American President']
MATCH p = (michael {name: 'Michael Douglas'})-->() RETURN p
// 結果:[Node[2]\{name:"Michael Douglas"\},:ACTED_IN[5]\{role:"President Andrew Shepherd"\},Node[6]\{title:"The American President"\}]
MATCH (a)-[r]-(b) WHERE id(r)=0 RETURN a,b
// 嘗試匹配兩個方向的關係
MATCH (martin:Person { name: 'Martin Sheen' }), (oliver:Person { name: 'Oliver Stone' }),
p = shortestPath((martin)-[*..15]-(oliver))
RETURN p
MATCH (martin:Person { name: 'Martin Sheen' }), (oliver:Person { name: 'Oliver Stone' }),
p = shortestPath((martin)-[*..15]-(oliver))
WHERE NONE (r IN rels(p) WHERE type(r) = 'FATHER') // WHERE斷言確保不考慮兩個節點間的父親/兒子關係
RETURN p
MATCH (martin:Person { name: 'Martin Sheen' }), (michael:Person { name: 'Michael Douglas' }),
p = allShortestPaths((martin)-[*]-(michael))
RETURN p
MATCH (a:Movie {title: 'Wall Street'}) OPTIONAL MATCH (a)-->(x) RETURN x // 返回null,因爲沒有外向關係
MATCH (n) WHERE n:Swedish AND n.name = 'Peter' OR NOT exists(n.name) AND n[toLower('AGE')] < 30 RETURN n
// has被exists代替了
MATCH (n) WHERE n.name = ~'(?i)ANDR.*' RETURN n // 非大小寫敏感的正則表達式
MATCH (tobias { name: 'Tobias' }), (others)
WHERE others.name IN ['Andres', 'Peter'] AND (tobias)<--(others) // 模式作爲斷言
RETURN others
MATCH (n)-[r]->() WHERE n.name = 'Andres' AND type(r) = ~'K.*' RETURN r
MATCH (n) WHERE n.belt = 'white' OR n.belt IS NULL RETURN n
CREATE (n:Person:Swedish) RETURN n // 多標籤節點
MATCH (`Tom Smith` { name: 'Tom Smith' }) RETURN `Tom Smith`.name AS source