【Neo4j cypher命令】 使用

零、引言

圖庫Neo4j使用cypher語句爲基本操作語言,本文總結一些關鍵字的使用方法

一、關鍵詞總結

1.1 Load csv 讀取文件

load csv with headers from 'file:///ces.csv' as line with line, linenumber()-1 as number 
call apoc.create.node([line.table],{table:line.table, ziduan:line.ziduan}) yield node return number
  1. 行終止標識和系統有關,例如在 Unix 中是 \n,在 Windows 上是 \r\n。 如windows環境導入LOAD CSV FROM 'file:///F:\\code\\java\\helloworld\\artists.csv' AS line
  2. 分隔符必須是逗號,除非用通過 FIELDTERMINATOR 特殊指定
  3. 如果字符串是用雙引號引起來的,數據讀入後會將雙引號去掉
  4. 任何需要轉義的字符都可以通過反斜線 \ 來轉義
  5. 要訪問本地(在數據庫服務器上)文件,使用 file:/// 路徑。除此之外,可以使用任何 HTTPS,HTTP 和 FTP 協議
  6. LOAD CSV導入數據, 可配合使用apoc.node.create() 動態添加單標籤,多標籤
  7. LOAD CSV是在線導入(導入數據量和效率一般), 使用neo4j-admin import 是離線導入,必須斷服務
CALL apoc.export.cypher.all('export.cypher',{format:'cypher-shell'})
  1. 全量導入圖庫所有內容,全圖導出到 import目錄下
  2. 若要載入,需在命令行中執行cat export.cypher | cypher-shell -u neo4j -p neo4j 並重啓neo4j服務

1.2 create 創建實體或關係

  1. 最簡單的創建實體和關係(不帶屬性)
    create (n:Person)-[:LOVES]->(m:Dog)
  2. 創建2個或多個屬性的實體
    create (z:ziduan{name:"f_name",table:"dianlibiao"}) return count(*)
  3. 創建帶屬性的實體和關係
    create (n:Person{name:"李四"})-[:FEAR{level:1}]->(t:Tiger{type:"東北虎"})
  4. 對實體間創建關係
    match (n:Person{name:""王五""}), (m:Person{name:"趙六"}) create (n)-[k:KNOW]->(m) return k

1.3 delete 刪除實體或關係

  1. 先用match查找已有實體、關係, 再用delete刪除關係
    match (n:Person{name:"李四"})-[f:FEAR]->(t:Tiger) delete f
  2. 刪除所有節點中的bian關係
    match(m)-[b:bian]-(n) delete b
  3. match查詢實體,delete刪除實體
    match (n:Person{name:"李四"}) delete n
  4. 同時刪除實體和關係
    match(n) detach delete n
  5. 刪除所有節點
    match (n) delete n
  6. 刪除所有節點並級聯刪除關係
    match (n) detach delete n
  7. 刪除Loc標籤的所有結點和關係
    MATCH (r:Loc) DETACH DELETE r

1.4 match 查詢節點和關係

  • match 查詢類似與關係型數據庫中的 select , 其語法結構如下:
  match 
      (node)-[relationship]->(node)
  where
      (node  |  relationship)
  return 
        (node | relationship)

match (n:Persion)-[:HAS_PHONE]->(p:Phone) where n.name="姓名6" return n, p  limit 10

n: 表示別名,這裏定義了不同實體的別名n 和 p
:HAS_PHONE 表示關係名稱
() 圓括號裏面表示實體 [] 方括號裏面表示關係,都是英文狀態下
()-[]->() 表示實體-關係-實體 該關係是有方向的,若要表示無方向的關係,則用: ()-[]-()

  1. 查詢所有實體節點
    match(n) return n
  2. 根據id查找實體
match (t:Tiger) where id(t)=1837 return t
match (t:Tiger) where id(t)=1837 delete t
  1. 多度關係查詢
match (n:Persion)-[:HAS_PHONE]->(p:Phone)-[:CALL]->(p1: Persion) where n.name=“姓名6” return n, p,p1  limit 10
  1. 利用關係查詢, 不限定實體只限定關係的查詢
match p=()-[c: CALL]->() return p limit 10
  1. 根據實體屬性匹配正則查詢, 使用通配符,通配符前要加~
match (n:USERS) where n.name=~'Jack.*' return n limit 10
  1. 包含查詢 使用關鍵詞contains
match (n:USERS) where n.name= contains 'J'  return n limit 10
  1. 附帶屬性多實體查詢, 逗號隔開,注意語法
match (n:Person{name:"王五"}), (m:Person{name:"趙六"}) return n,m
  1. 查詢多種label節點,並進行過濾
match(n) where n:標籤1 or n:標籤B  return distinct n;
  • distinct * 關鍵字表示返回節點不重複
  1. 返回非某幾類標籤,注意使用 not and 關鍵字
match(n) where not n:標籤1 and not n:標籤B  return distinct n;

1.5 set 修改實體標籤或屬性

  1. 給實體增加標籤
match (t:Tiger) where id(t)=1837 set t:A  return t	

本質上是給實體增加一個標籤,一個實體可以有多個標籤
此時該實體有兩個標籤A Tiger
2. 給實體增加屬性

match (a:A) where id(t)=1837 set a.年齡=10  return a
  1. 給關係增加屬性
match (n:Person)-[l:LOVE]->(:Person) set l.date="1990" return n, l                                                           |        |	
  1. 給所有節點增加標籤
match(n) set n:table return n

1.6 索引的創建與刪除(索引是在屬性上創建的,用於加速檢索)

  1. 創建索引 (在Person標籤的name屬性上創建索引)
create index on :Person(name)
  1. 刪除索引
drop index on :Person(name)
  1. 創建唯一索引(在實體Person的name屬性上創建唯一索引)
create constraint on (p:Person) assert (p.name)  is  unique
  1. 刪除唯一索引
drop constraint on (p:Person) assert (p.name)  is  unique

1.7 單條最短路徑

match (p1:Person{name:"姓名2"}),(p2:Person{name:"姓名10"}), p=shortestpath((p1)-[*..10]-(p2)) return p

shortestpath()用於查詢最短路徑 [*..10] 表示關係中不超過10度關係

1.8 多條最短路徑

match (p1:Person{name:"姓名2"}),(p2:Person{name:"姓名10"}), p=allshortestpaths((p1)-[*..10]-(p2)) return p

1.9 collect 將多個值轉換成列表

match (n:ERP_anek) with collect(n) as list call apoc.refactor.mergeNodes(list, {properties:{ziduan:'combine'}}) yield node return count(node)

表ERP_anek是實體,屬性爲該表字段,數據導入後,將多個實體合併

1.10 unwind 將列表拆分成多個值

WITH [[1, 2],[3, 4], 5] AS nested
UNWIND nested AS x
UNWIND x AS y
RETURN y

依次遍歷拆開多個列表

1.11 yield 依次迭代生成對象

CALL db.labels() YIELD label
WHERE label CONTAINS 'User'
RETURN count(label) AS numLabels

1、yield和call 關鍵字 通常一起使用
2、call 後跟圖庫已實現的procedure,如各種apoc功能, 而yield則爲得到
3、call後需加上 procedure的入參;而yield後可加 procedure的返回值

1.12 merge 有關係則返回,沒有則創建關係

match (n:Person{name:"王五"}), (m:Person{name:"趙六"}) merge (n)-[l:LOVE]->(m) return l

match (n),(m) where n=m merge (n)-[t:TABLE{table_name:n.table}]-(m) return t

1.13 optional match 可選擇匹配,若匹配結果包含空,則用NULL佔位

OPTIONAL MATCH (n)-[r]->(m) RETURN m

匹配結果集中如果有丟的部分,則會用null來補充

1.14 XXX with 字符串開頭結尾匹配

  1. start with 匹配字符串的開頭
  MATCH (n)
  WHERE n.name STARTS WITH '張'
  RETURN n
  1. end with 匹配字符串的結尾
  MATCH (n)
  WHERE n.name ENDS WITH '三'
  RETURN n

1.15 得到邊上的節點

  1. startNode(rel) 得到一條關係rel對應的起始節點
  2. endNode(rel) 得到一條關係rel對應的中止節點

1.16 得到某節點的id或key

  1. id(node) 得到某節點的id值
  2. keys(node) 得到某節點的key

1.16 split 對指定字符串用指定分隔符split

模板 :
split(original, splitDelimiter)
使用splitDelimiter切分original

LOAD CSV WITH HEADERS FROM 'file:///employees.csv' AS row
MERGE (e:Employee {employeeId: row.Id, email: row.Email})
WITH e, row
UNWIND split(row.Skills, ':') AS skill

1.17 count 統計指定標籤下節點個數

MERGE (e:Employee {employeeId: row.employeeId, name: row.Name})
RETURN count(e);

統計指定標籤下節點個數

1.18 distinct 對返回結果去重

WITH [1,1,2,2] AS coll UNWIND coll AS x
WITH DISTINCT x
RETURN collect(x) AS SET

1.19 linenumber() 返回按行操作後的行號

LOAD CSV FROM '{csv-dir}/artists.csv' AS line RETURN linenumber() AS number, line   XXXX

按行導入csv,並返回linenumber

1.20 USING PERIODIC COMMIT 多行語句提交

通常用於批量執行語句中,可將多條語句累計一定量後提交, 如load csv 按行載入數據,可以每1000行提交一版

USING PERIODIC COMMIT 1000 
LOAD CSV FROM '{csv-dir}/artists.csv' AS line

1、指示Neo4j在多行之後執行提交
2、減少了事務狀態的內存開銷
3、提交將每1000行發生一次

1.21 grant 賦權

grant 操作需要企業版,社區版由於無法賦權,所以很多高性能操作無法實現

Grant 賦權 共包含8大類:
1)爲圖的不同部分定義了寫特權:
CREATE -允許創建節點和關係。
DELETE -允許刪除節點和關係。
SET LABEL-允許使用SET子句設置指定的節點標籤。
REMOVE LABEL-允許使用REMOVE子句刪除指定的節點標籤。
SET PROPERTY -允許在節點和關係上設置屬性。
2)還有一些組合特權,這些特權組合了上述特定特權:
MERGE-允許match,create和set屬性以允許MERGE命令。
WRITE -允許在整個圖形上進行所有寫操作。
ALL GRAPH PRIVILEGES -允許在整個圖形上進行所有讀取和寫入操作。

grant create on graph neo4j elements * to neo4j   *給neo4j用戶增加對neo4j圖庫的create權限*

Neo4j Cypher Refcard 4.1 語法使用查找表

1.22 apoc.periodid.iterate 並行可迭代過程 需grant賦權

CALL apoc.periodic.iterate( statement1, statement2, { batchSize:1000, iterateList:true, parallel:false, params:{}, concurrency:50, retries:0 } ) 
YIELD batches, total

1、建議始終設置iterateList:true,因爲這樣使得一個批次中所有內查詢(由batchSize決定)會作爲一個事務被提交、從而提高運行效率。
2、僅當數據庫是存儲在SSD(固態硬盤)時才使用parallel:true選項,因爲SSD具有更好的隨機讀寫速率。如果是物理硬盤則不要使用並行選項,因爲這反而會降低整體執行效率。
3、併發數concurrency通常設置成分配給數據庫服務運行的CPU內核數的整數倍。例如,如果Neo4j服務器運行在8個CPU內核的虛擬或物理主機上,那麼concurrency可以是8、16、24等值。
4、併發執行時,如果不同線程需要對同一數據庫對象(節點或關係)進行更新,先執行的線程會對待更新的數據庫對象加鎖(locking),這時其它線程的更新會被阻塞、並報告“鎖獲取失敗”或者Java NullPointerException空指針錯誤。
一種解決方法是設置重試次數retries,每次重試會等待100ms。
如果還是出現死鎖,則不使用並行執行。

1.23 apoc.cypher.parallel並行化操作

call apoc.cypher.parallel('match (n:ERP_anek),(m) where not m:ERP_anek and n.ziduan = m.ziduan merge (n)-[b:bian{lianlu:n.ziduan}]-(m) return b.lianlu', {table: ['ERP_anek','ERP_crhd','ERP_iseg']},'table') yield value 

需要grant 添加權限,而grant 操作需要企業版

未完待續...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章