Neo4j-cypher QL基礎


cypher :一種聲明式圖查詢語言,表達高效查詢和更新圖數據庫。

   先來感受下neo4j優雅的web界面及圖(關系)處理能力

      

一、基礎知識

1、基礎概念

變量:用於引用搜索模式(pattern),變量可以忽略,如果不需要引用;

節點:對象,可帶若干key-value屬性,可帶標簽;

關系:連接節點(有類型、帶方向),可帶若干名key-value屬性;

標簽:label沒有屬性。

2、屬性訪問:可以通過.訪問;

3、常規運算:

(1)常規運算 DISTINCT, ., []

(2)算數運算 +, -, *, /, %, ^

(3)比較運算 =, <>, <, >, <=, >=, IS NULL, IS NOT NULL

(4)邏輯運算 AND, OR, XOR(異或), NOT

(5)字符串操作 +

(6)List操作 +, IN, [x], [x .. y], not actor in

(7)正則操作 =~ //后面可使用正則表達式匹配規則

(8)字符串匹配 STARTS WITH, ENDS WITH, CONTAINS

(9)示例:

(9.1)XOR使用

MATCH (n) WHERE n.name = 'Peter' XOR (n.age < 30 AND n.name = "Tobias") OR NOT (n.name = "Tobias" OR n.name="Peter") RETURN n

(9.2)CONTAINS使用

MATCH (n:ResNode)-[r:INSTANCE_OF]->(m:ResourceTypeNode) WHERE m.typeNum IN {resTypeNums} AND n.discarded <> true AND m.discarded <> true AND n.props.areaPropKey CONTAINS {areaCode} RETURN n

(9.3)in使用

match (n:Template) where n.id in ['templateLabel_QP42X','templateLabel_network','templateLabel_ziEzh'] return n

二、cypherQL 基礎

0、節點:

0.1)、創建節點

單個節點 create (n)

創建帶一個標簽的節點 create (n:Person { name: 'Tom Hanks', born: 1956 }) return n;

創建帶兩個標簽的節點 create (n:Person:Student)

返回創建的節點 create (a{name:"tom"}) return a;

0.2)、查詢節點

match(n) return n;//查詢所有節點

match(n) where n.born<1955 return n;//查詢符合條件(通過where子句添加條件)的節點

match(n:Movie) return n;//查詢具有標簽的節點

match(n{name:'Tom Hanks'}) return n;//查詢具有屬性的節點

1、關系:

1)開始節點-[變量名:關系類型{key:value}]->結束節點,創建關系時,必須指定關系類型;

2) -- 有關系

  --> <--有方向的關系

3)  創建關系

   //創建新的節點和新的關系

   create (a)-[r:RELATION]->(b) return r;

  //創建關系的同時設置屬性

   create (a)-[r:RELATION{name:a.name+"<->"+b.name}]->(b) return r;

   create (n:Lable1{title:"a",pic:"b"}) -[r:RELATION{id:"test"}]-> (m:Lable2{title:"a1",pic:"b1"});

   create (a)-[r:RELATION]->(b) set r.id = "test", a.title="a" return a,r,b;

  //已有節點創建新的關系

   match (a:Person),(b:Person) where a.name="zhang" and b.name="lisi" create (a)-[r:RELATION]->(b) return a,r,b;

  注意:為現有的兩個節點添加了關系。這種情況我們需要用match先找到兩個節點,然后在給兩個節點添加關系。如果沒有match就等同於新建節點。現有的節點被忽略

  完整創建:三個關系兩個節點

   create p=(an{name:"an"})-[:WORKS_AT]->(neo)<[:WORKS_AT]-(match{name:"tom"}) return p;

  注意:

  1,創建節點和關系語句必須一次執行完,否則如上面例子所述,創建關系時()中的節點被認為是新的節點。
  2,分號是一個語句的結尾

4)  set

  //更新一個節點和關系的標簽或屬性 更改屬性

   match (n{name:"tom"}) set n.name="tom1" return n;

  //設置多個屬性:

  MATCH (n { name: 'Andres' }) SET n.position = 'Developer', n.surname = 'Taylor'

  //刪除屬性

   match (n{name:"tom"}) set n.name=null return n;

  //更改標簽

   match (n{name:"tom"}) set n:Label return n; match (n{name:"tom"}) set n:Label1:Label2 return n;

  //節點和關系之間復制屬性 在節點和關系之間復制屬性:

  MATCH (at { name: 'Andres' }),(pn { name: 'Peter' }) SET at = pn RETURN at, pn;

  //FOREACH: 為所有節點設置mark屬性

  MATCH p =(begin)-[*]->(END ) WHERE begin.name='A' AND END .name='D' FOREACH (n IN nodes(p)| SET n.marked = TRUE )

5)  刪除

  5.1)刪除節點和關系 delete

  刪除單個節點 match (n:Label) delete n;

  刪除節點和連接它的關系 match (n{name:"tom"})-[r]-() delete n,r;

  只刪除關系 match (n{name:"tom"})-[r]-() delete r;

  刪除所有節點和關系(慎用)match(n) optional match (n)-[r]-() delete n,r;

  刪除節點及其關系 MATCH (n:Department{name: "test",alias: ""}) DETACH DELETE n

  5.2)刪除標簽和屬性 remove

  刪除屬性 match (n{name:"tom"}) remove n.age return n;

  刪除標簽 match (n:{name:"tom"}) remove n:Label return n;

  刪除多重標簽 match (n:{name:"tom"}) remove n:Label:Label1 return n;

  注:set也可以刪除屬性 match (n:User{name:'jack'}) set n.name = null return n;

6)match

//查詢所有節點 match (n) return n;

//查詢指定標簽的節點 match(n)--(m:Movie) return n; MATCH (n:templatelabel2) RETURN n LIMIT 25;

//關聯節點 match (person{name:'tom'})--(movie) return movie;

//關聯標簽 match (person{name:'tom'})--(movie:Movie) return movie;

//關系查詢 match (person{name:'tom'})-->(movie) return movie;

match (person{name:'tom'})-[r]->(movie) return r;

match (:Person(name:'tom'))-[r]->(Movie) return r,type(r);//返回關系類型

查詢特定的關系,通過[variable:RelationshipType{key:value}]指定關系的類型和屬性

match (:Person{name:tom})-[r:ACTED_IN(roles:'forrest')]->(movie) return r,type(r);

6.1)  where子句

過濾標簽:MATCH (n) WHERE n:Swedish RETURN n

過濾屬性:MATCH (n) WHERE n.age < 30 RETURN n

正則/模糊查詢:MATCH (n) WHERE n.name =~ 'Tob.' RETURN n

使用NOT:MATCH(persons),(peter { name: 'Peter' }) WHERE NOT (persons)-->(peter) RETURN persons

使用屬性:MATCH (n) WHERE (n)-[:KNOWS]-({ name:'Tobias' }) RETURN n

關系類型:MATCH (n)-[r]->() WHERE n.name='Andres' AND type(r)=~ 'K.' RETURN r

使用IN:MATCH (a) WHERE a.name IN ["Peter", "Tobias"] RETURN a

過濾NULL:MATCH (person) WHERE person.name = 'Peter' AND person.belt IS NULL RETURN person

使用NOT...IN: MATCH (n:ResNode)-[r:INSTANCE_OF]->(m:ResourceTypeNode) where not m.typeNum in ["USER","ORG"] return count(n)

6.2)START

START n=node:nodes(name = "A") RETURN n

START r=relationship:rels(name = "LISI") RETURN r

START n=node:nodes("name:A") RETURN n

6.3)聚合函數

count:MATCH (n { name: 'A' })-->(x) RETURN n, count(*)

sum:MATCH (n:Person) RETURN sum(n.property)

avg:MATCH (n:Person) RETURN avg(n.property)

max:MATCH (n:Person) RETURN max(n.property)

min:MATCH (n:Person) RETURN min(n.property)

6.4)常規函數

return

返回一個節點:match (n {name:"B"}) return n;

返回一個關系:match (n {name:"A"})-[r:KNOWS]->(c) return r;

返回一個屬性:match (n {name:"A"}) return n.name;

返回所有節點:match p=(a {name:"A"})-[r]->(b) return *;

列別名: match (a {name:"A"}) return a.age as thisisage;

表達式: match (a {name:"A"}) return a.age >30 ,"literal",(a)-->();

唯一結果:match (a {name:"A"})-->(b) return distinct b;

order by

通過屬性排序所有節點:match (n) return n order by n.name;

多個屬性排序:match (n) return n order n.name,n.age;

指定排序方式:match (n) return n order by n.name desc;

NULL值的排序:match (n) return n.length,n order by n.length;

limit

match (n) return n order by n.name limit 3;

skip

match (n) return n order by n.name skip 3;

match (n) return n order by n.name skip 1 limit 3;

with

主要用途:

1、通過使用oder by 和limit,with可以限制傳入下一個match子查詢語句的實體數目。
2、對聚合值過濾。

過濾聚合函數的結果:(常用於對統計結果的操作) MATCH (david { name: "David" })--(otherPerson)-->() WITH otherPerson, count(*) AS foaf WHERE foaf > 1 RETURN otherPerson;

collect前排序結果:MATCH (n) WITH n ORDER BY n.name DESC LIMIT 3 RETURN collect(n.name;

limit搜索路徑的分支: 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,3] as coll unwind coll x with distinct x return coll(x) as set;

optional

optional match 外連接(表之間關聯查詢,查詢出兩張表的數據,非笛卡兒積)(optional 貌似可以省略---待測) 與match類似,只是如果沒有匹配上,則使用null作為沒有匹配上的模式。類似sql中的外連接; 匹配關系:match (a:Movie {title:"Wall Street"}) optional match (a)-->(x) return x; 如果沒有返回null; 匹配屬性:match (a:Movie {title:"Wall Street"}) optional match (a)-->(x) return x,x.name

//返回兩張表的結果 match (n:ResNode)-[r:INSTANCE_OF]-(m:ResourceTypeNode) where m.typeNum = "2" match(n1:ResNode)-[r0:INSTANCE_OF]-(m1:ResourceTypeNode) where m1.typeNum = "vpn" return n,n1

//返回兩張表的結果 match (n:ResNode)-[r:INSTANCE_OF]-(m:ResourceTypeNode) where m.typeNum = "2" optional match(n1:ResNode)-[r0:INSTANCE_OF]-(m1:ResourceTypeNode) where m1.typeNum = "vpn" return n,n1

range() 函數
match(n:ResNode) where n.createTime in range(1579155490014,1579155491014) return n limit 5

 

斷言函數

   指對給定的輸入返回true或者false的布爾函數。它們主要用於查詢的WHERE部分過濾子圖

1.1 all() 判斷是否一個斷言適用於列表中的所有元素。

    語法: all(variable IN list WHERE predicate)

    參數:

  list:返回列表的表達式

  variable:用於斷言中的變量

  predicate:用於測試列表中所有元素的斷言

  MATCH p =(a)-[*1..3]->(b) WHERE ALL (x IN nodes(p) WHERE x.age > 30) RETURN p

 

1.2 any() 判斷是否一個斷言至少適用於列表中的一個元素。

  語法: any(variable IN list WHERE predicate)

  參數:

    list:返回列表的表達式

    variable:用於斷言中的變量

    predicate:用於測試列表中所有元素的斷言

  MATCH (a) RETURN ANY (x IN a.array WHERE x = 'one') RETURN a 返回路徑中的所有節點的array數組屬性中至少有一個值為'one'。

 

1.3 none() 如果斷言不適用於列表中的任何元素,則返回true。

  語法: none(variable IN list WHERE predicate)

  參數:

  list:返回列表的表達式

     variable:用於斷言中的變量=

        predicate:用於測試列表中所有元素的斷言

  MATCH p =(n)-[*1..3]->(b) WHERE n.name = 'Alice' AND NONE (x IN nodes(p) WHERE x.age = 25) RETURN p  返回的路徑中沒有節點的age屬性值為25。

 

1.4 single() 如果斷言剛好只適用於列表中的某一個元素,則返回true。

  語法: single(variable IN list WHERE predicate)

  參數:

  list:返回列表的表達式

  variable:用於斷言中的變量

  predicate:用於測試列表中所有元素的斷言

  MATCH p =(n)-->(b) WHERE n.name = 'Alice' AND SINGLE (var IN nodes(p) WHERE var.eyes = 'blue') RETURN p 每條返回的路徑中剛好只有一個節點的eyes屬性值為'blue'。

 

1.5 exists() 如果數據庫中存在該模式或者節點中存在該屬性時,則返回true。

  語法: exists( pattern-or-property )

  參數: pattern-or-property:模式或者屬性(以’variable.prop’的形式)

  MATCH (n) WHERE exists(n.name) RETURN n.name AS name, exists((n)-[:MARRIED]->()) AS is_married 返回了所有節點的name屬性和一個指示是否已婚的true/false值。

 

標量(Scalar)函數

  標量(Scalar)函數:指返回一個單值。

2.1 size()
  使用size()返回表中元素的個數。
  語法: size( list )
  參數: list:返回列表的表達式
  RETURN size(['Alice', 'Bob']) AS col 返回了list中元素的個數。

2.2 模式表達式的size
  這里的size()的參數不是一個列表,而是一個模式表達式匹配到的查詢結果集。計算的是結果集元素的個數,而不是表達式本身的長度。
  語法: size( pattern expression )
  參數: pattern expression:返回列表的模式表達式
  MATCH (a) WHERE a.name = 'Alice' RETURN size((a)-->()-->()) AS fof
  返回了模式表達式匹配到的子圖的個數

2.3 length()
  使用length()函數返回路徑的長度。
  語法: length( path )
  參數: path:返回路徑的表達式
  MATCH p =(a)-->(b)-->(c) WHERE a.name = 'Alice' RETURN length(p)

2.4 字符串的長度
  語法: length( string )
  參數: string:返回字符串的表達式
  RETURN length('qwer')

  MATCH (a) WHERE length(a.name)> 6 RETURN length(a.name)
  查詢返回了name為’Charlie’的長度。

2.5 type()
  返回字符串代表的關系類型。
  語法: type( relationship )
  參數: relationship:一個關系
  MATCH (n)-[r]->() WHERE n.name = 'Alice' RETURN type(r)
  查詢返回了關系r的關系類型。

2.6 id()
  返回關系或者節點的id。
  語法: id( property-container )
  參數: property-container:一個節點或者關系
  MATCH (a) RETURN id(a) 返回了5個節點的id。

2.7 coalesce()
  返回表達式列表中的第一個非空的值。如果所有的實參都為空 ,則返回null。
  參數: expression:表達式,可能返回null。
  MATCH (a) WHERE a.name = 'Alice' RETURN coalesce(a.hairColor, a.eyes)

2.8 head()
  head()返回列表中的第一個元素。
  語法: head( expression )
  參數: expression:返回列表的表達式
  MATCH (a) WHERE a.name = 'Eskil' RETURN a.array, head(a.array)
  MATCH p=(n)-[r]->() WHERE n.name = 'Alice' return head(nodes(p))
  返回了路徑中的第一個節點。

2.9 last()
  last()返回列表中的最后一個元素。
  語法: last( expression )
  參數: expression:返回列表的表達式
  MATCH (a) WHERE a.name = 'Eskil' RETURN a.array, last(a.array)
  返回了路徑中的最后一個節點。

2.10 timestamp()
  timestamp()返回當前時間與1970年1月1日午夜之間的差值,單位以毫秒計算。它在整個查詢中始終返回同一個值,即使是在一個運行時間很長的查詢中。
  語法: timestamp()
  RETURN timestamp()
  以毫秒返回當前時間。

2.11 startNode() 返回一個關系的開始節點。
  語法: startNode( relationship )
  參數: relationship:返回關系的表達式
  MATCH ()-[r]-() WHERE id(r)=0 RETURN startNode(r)

2.12 endNode()
  endNode()返回一個關系的結束節點。
  語法: endNode( relationship )
  參數: relationship:返回關系的表達式
  MATCH ()-[r]-() WHERE id(r)=0 RETURN startNode(r),endNode(r)

2.13 properties()
  properties()將實參轉為屬性值的map。如果實參是一個節點或者關系,返回的就是節點或關系的屬性的map。如果實參已經是一個map了,那么原樣返回結果。
  語法: properties( expression )
  參數: expression:返回節點,關系或者map的表達式
  match (n) where id(n) =0 RETURN properties(n)

2.14 toInt()
  toInt()將實參轉換為一個整數。字符串會被解析為一個整數。如果解析失敗,將返回null。浮點數將被強制轉換為整數。

2.15 toFloat
  toFloat()將實參轉換為浮點數。字符串會被解析為一個浮點數。如果解析失敗,將返回null。整數將被強制轉換為浮點數。

 

其他函數---模式(索引、約束、統計)

索引

標簽上創建索引:create index on :Person(name)

刪除索引:drop index on :Person(name)

約束

創建唯一約束:CREATE CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE

刪除約束:DROP CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE

2、更新圖形

創建一個完整的path path由節點和關系構成,當路徑中的關系或節點不存在時,neo4j會自動創建; CREATE p =(vic:Worker:Person{ name:'vic',title:"Developer" })-[:WORKS_AT]->(neo)<-[:WORKS_AT]-(michael:Worker:Person { name: 'Michael',title:"Manager" }) RETURN p 變量neo代表的節點沒有任何屬性,但是,其有一個ID值,通過ID值為該節點設置屬性和標簽

2)為節點增加屬性 match(n) where id(n)=7 set n.name='neo' return n;

3)為節點增加標簽 match (n) where id(n)=7 set n:Company return n;

4)為關系增加屬性 match (n) <-[r]-(m) where id(n)=7 and id(m)=8 set r.team='azure' return n;

3、實體相關函數

match (:Person{name:'tom'})-[r]->(movie) return id(r);

match (:Person{name:'tom'})-[r]->(movie) return type(r);

match (:Person{name:'tom'})-[r]->(movie) return lables(movie);

MATCH (a) WHERE a.name = 'Alice' RETURN keys(a)

CREATE (p:Person { name: 'Stefan', city: 'Berlin' }) RETURN properties(p)

4、merge的作用

節點存在時,匹配該節點; 節點不存在時,創建新的節點,功能是match子句和creat的組合。 通過merge子句,可以指定圖形中必須一個節點,該節點必須具有特定的標簽,屬性等,如果不存在,merge子句將創建響應的節點。

 

5、復雜查詢

//排除查詢

MATCH (m:Lab1) WHERE m.p1 IN {p1s} AND m.discarded <> true WITH COLLECT(m) AS ns MATCH (n:Lab1) WHERE n.p2<> true AND NOT n IN ns RETURN n;

match (m:Lab1) where m.p2 in ["a","c","b"] with collect(m) as ress MATCH (n:Lab1) where not n in ress RETURN n LIMIT 3;

 

//關系排除查詢

MATCH (n:Lab1) where not((n:Lab1)-[:rType]->(:Lab2)) RETURN n.p1,n.p2

 

//查詢最近的n條記錄

MATCH (n:Lab1)-[r:relation*1..30]->(m:Lab2) where n.his ='start' RETURN n,r,m

 

//關系深度

MATCH p=(n)-[*1..5]->(m) RETURN p //匹配從n到m,任意關系,深度1到5的節點

MATCH p=(n)-[*]->(m) RETURN p //匹配從n到m,任意關系、任意深度的節點

 

//查詢id前52位重復的關系

MATCH (n:Lab1)-[r:relation]-(m:Lab2) WITH n, m, COLLECT (SUBSTRING(r.id,0,52)) as rr WHERE size(rr)>1 and n.p1 = "a" and m.p1 = "b" return rr

 

 

注意事項:

1)節點所屬label不能為空(neo4j默認以當前類名作為label名稱);需要通過label進行節點查詢;

2)label是對關系型數據庫中表的延伸,label中可以存放同一類型的節點(關系型數據庫中的記錄),也可以存放不同類型的節點(可以存放多個表中的記錄)。

 

感謝閱讀,參考了不少大佬資源,如需轉載,請注明出處,謝謝!https://www.cnblogs.com/huyangshu-fs/p/13620260.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM