TL;DR
- 場景:圖數據庫項目中高頻用到的字符串函數、聚合、關係函數與 shortestPath,多跳查詢易踩坑。
- 結論:以 Cypher 5/Neo4j 5.x 為基線,先掌握 toLower/trim/replace/split/substring/size、startNode/endNode、可變長度路徑;避免一次多語句與未綁定變量。
- 產出:函數清單與示例整理、版本兼容矩陣、錯誤速查卡(覆蓋 WITH 傳參、shortestPath 約束、屬性缺失、類型不匹配等)。
CQL函數
字符串函數
基本字符串函數
- toString()
- 功能:將任意類型的值轉換為字符串形式
- 示例:
RETURN toString(123)→ 返回 “123” - 應用場景:將數值、布爾值等非字符串類型轉換為字符串以便與其他字符串連接或比較
- toUpper()
- 功能:將字符串轉換為大寫形式
- 示例:
RETURN toUpper("neo4j")→ 返回 “NEO4J” - 應用場景:統一大小寫格式進行字符串比較或顯示
- toLower()
- 功能:將字符串轉換為小寫形式
- 示例:
RETURN toLower("Neo4J")→ 返回 “neo4j” - 應用場景:同上,用於標準化字符串格式
字符串操作函數
- trim()
- 功能:去除字符串兩端的空白字符
- 示例:
RETURN trim(" Neo4j ")→ 返回 “Neo4j” - 變體:
lTrim()- 僅去除左側空白rTrim()- 僅去除右側空白
- replace()
- 功能:替換字符串中的子串
- 語法:
replace(原始字符串, 要替換的子串, 替換為的子串) - 示例:
RETURN replace("Hello World", "World", "Neo4j")→ 返回 “Hello Neo4j” - 應用場景:批量修改數據中的特定文本
- substring()
- 功能:提取字符串的一部分
- 語法:
substring(字符串, 起始位置)(從0開始計數)substring(字符串, 起始位置, 長度)
- 示例:
RETURN substring("Neo4j", 3)→ 返回 “4j”RETURN substring("Neo4j", 1, 3)→ 返回 “eo4”
字符串信息函數
- size()
- 功能:返回字符串的字符長度
- 示例:
RETURN size("Neo4j")→ 返回 5 - 注意:與
length()函數功能相同,可以互換使用
- split()
- 功能:按分隔符將字符串分割為字符串數組
- 示例:
RETURN split("one,two,three", ",")→ 返回 [“one”, “two”, “three”] - 應用場景:處理CSV格式的數據或路徑字符串
- reverse()
- 功能:反轉字符串字符順序
- 示例:
RETURN reverse("Neo4j")→ 返回 “j4oeN”
字符串匹配函數
- contains()
- 功能:檢查字符串是否包含子串
- 示例:
RETURN contains("Neo4j", "4j")→ 返回 true - 應用場景:數據篩選或條件判斷
- startsWith()
- 功能:檢查字符串是否以指定前綴開頭
- 示例:
RETURN startsWith("Neo4j", "Neo")→ 返回 true
- endsWith()
- 功能:檢查字符串是否以指定後綴結尾
- 示例:
RETURN endsWith("Neo4j", "4j")→ 返回 true
- left() / right()
- 功能:
left(字符串, 長度)- 返回字符串左側指定長度的子串right(字符串, 長度)- 返回字符串右側指定長度的子串
- 示例:
RETURN left("Neo4j", 3)→ 返回 “Neo”RETURN right("Neo4j", 2)→ 返回 “4j”
特殊字符串處理
- toStringOrNull()
- 功能:嘗試將輸入轉換為字符串,失敗則返回null
- 與
toString()的區別:不會拋出異常,處理更安全
- toStringList()
- 功能:將列表中的元素轉換為字符串列表
- 示例:
RETURN toStringList([1, 2, true])→ 返回 [“1”, “2”, “true”]
實際應用示例
// 查詢名稱以特定前綴開頭且經過標準化的用户
MATCH (u:User)
WHERE startsWith(toLower(u.name), 'alex')
RETURN u.name, size(u.name) as nameLength
// 處理地址數據,標準化格式
MATCH (a:Address)
SET a.city = toUpper(trim(a.city)),
a.street = replace(a.street, "St.", "Street")
語法實例
基本的語法如下所示:
MATCH (p:Person)
RETURN ID(p),LOWER(p.character)
嘗試一個例子:
match(person:Person) RETURN ID(person), UPPER(person.character);
執行的結果如下所示,可以看到 UPPER 函數已經將結果轉換為大寫了:
聚合函數
對應的語法格式如下所示:
MATCH (p:Person)
RETURN MAX(p.money),SUM(p.money)
執行結果可以看到已經計算出來了,後半段截圖沒有截到:
關係函數
這裏我們元數據長這個樣子:
然後我們查詢 wzk5 的 friend 關係的:
match p = (:Person{name: "wzk5"})-[r:Friend]-(:Person) return STARTNODE(r);
可以看到查詢到了 wzk4 的內容:
最短Path
MATCH p=shortestPath( (node1)-[*]-(node2) )
RETURN length(p), nodes(p)
CQL多深度關係點
with關鍵字
這裏我們加入一些內容,讓整體變得複雜起來:
// 清理舊數據 (可選)
// MATCH (n:Person) WHERE n.name STARTS WITH "wzk" DETACH DELETE n;
// ====== 創建節點 =======
UNWIND range(1, 10) AS i
MERGE (:Person {name:"wzk" + i});
// ====== 創建多樣關係 =======
// 1)鏈式關係(長鏈)
MATCH (a:Person {name:"wzk1"}), (b:Person {name:"wzk2"})
MERGE (a)-[:Follow]->(b);
MATCH (b:Person {name:"wzk2"}), (c:Person {name:"wzk3"})
MERGE (b)-[:Friends]->(c);
MATCH (c:Person {name:"wzk3"}), (d:Person {name:"wzk4"})
MERGE (c)-[:Colleague]->(d);
MATCH (d:Person {name:"wzk4"}), (e:Person {name:"wzk5"})
MERGE (d)-[:Knows]->(e);
// 2)三角結構(循環)
MATCH (p1:Person {name:"wzk3"}),(p2:Person {name:"wzk6"}),(p3:Person {name:"wzk7"})
MERGE (p1)-[:Friends]->(p2)
MERGE (p2)-[:Friends]->(p3)
MERGE (p3)-[:Friends]->(p1);
// 3)星型關係(hub-and-spoke)
MATCH (c:Person {name:"wzk5"}), (n:Person)
WHERE n.name IN ["wzk6","wzk7","wzk8","wzk9"]
MERGE (c)-[:Follow]->(n)
MERGE (n)-[:Knows]->(c);
// 4)雙向 Couple(特意製造有向+無向混合)
MATCH (a:Person {name:"wzk1"}),(b:Person {name:"wzk8"})
MERGE (a)-[:Couple]->(b)
MERGE (b)-[:Couple]->(a);
// 5)複雜跨層跳躍
MATCH (x:Person {name:"wzk9"}),(y:Person {name:"wzk10"})
MERGE (x)-[:Colleague]->(y);
MATCH (y:Person {name:"wzk10"}),(z:Person {name:"wzk2"})
MERGE (y)-[:Follow]->(z);
// 6)製造稠密關係(高節點度,用於性能測試)
MATCH (p:Person), (p2:Person)
WHERE p.name STARTS WITH "wzk"
AND p2.name STARTS WITH "wzk"
AND p <> p2
AND rand() < 0.15 // 15% 概率生成一條邊
MERGE (p)-[:Knows]->(p2);
整體執行完之後,會生成類似這樣的結構:
直接拼接關係節點查詢
match (na:Person{name:"wzk1"})-[re]->(nb:Person)-[re2]->(nc:Person) return na,re,nb,re2,nc
運行結果如下所示:
使用深度運算符
當實現多深度關係節點查詢時,顯然使用以上方式比較繁瑣。
match data = (na:Person{name:"wzk1"})-[*1..2]-(nb:Person) return data
執行結果如下所示:
本文章為轉載內容,我們尊重原作者對文章享有的著作權。如有內容錯誤或侵權問題,歡迎原作者聯繫我們進行內容更正或刪除文章。