Neo4j學習筆記


1. 環境搭建

正好最近同學有一台阿里雲服務器借我玩,就嘗試着在服務器上搭了Neo4j。
環境:CentOS Linux release 7.4.1708 (Core)

安裝Java

安裝Neo4j需要Java環境。並且需要jdk1.8,所以低版本需要卸載重裝。

官網 復制下載鏈接,然后到命令行找一個目錄下載:
wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u151-b12/e758a0de34e24606bca991d704f6dcbf/jdk-8u151-linux-x64.rpm"
(開始直接wget下載,然后解壓一直出錯,最后發現下載的是...HTML document,真的是尷尬,然后找到了這個下載方法)
安裝:sudo rpm -ivh jdk-8u151-linux-x64.rpm
查看安裝版本:java -version
當看到

java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

Java安裝成功!
(我真的是...裝了好久...蠢哭)

安裝Neo4j

官網有 教程 安裝社區版。

[root@neo4j]# wget http://debian.neo4j.org/neotechnology.gpg.key  
[root@neo4j]# rpm --import neotechnology.gpg.key  
[root@neo4j]# cat <<EOF > /etc/yum.repos.d/neo4j.repo  
> [neo4j]  
> name=Neo4j Yum Repo  
> baseurl=http://yum.neo4j.org/stable  
> enabled=1  
> gpgcheck=1  
> EOF  
   
[root@neo4j]# yum install neo4j  -y  

嗯。。下載速度比較超級慢,等了十多分鍾。
查看安裝版本:

[root@neo4j]# neo4j version
OpenJDK 64-Bit Server VM warning: If the number of processors is expected to increase from one, then you should configure the number of parallel GC threads appropriately using -XX:ParallelGCThreads=N
neo4j 3.3.0

已經安裝成功,版本為3.3.0。

啟動Neo4j服務

啟動:neo4j console

Active database: graph.db
Directories in use:
  home:         /var/lib/neo4j
  config:       /etc/neo4j
  logs:         /var/log/neo4j
  plugins:      /var/lib/neo4j/plugins
  import:       /var/lib/neo4j/import
  data:         /var/lib/neo4j/data
  certificates: /var/lib/neo4j/certificates
  run:          /var/run/neo4j
Starting Neo4j.
OpenJDK 64-Bit Server VM warning: If the number of processors is expected to increase from one, then you should configure the number of parallel GC threads appropriately using -XX:ParallelGCThreads=N
2017-10-31 15:50:26.178+0000 WARN  dbms.directories.certificates is deprecated.
2017-10-31 15:50:26.221+0000 INFO  ======== Neo4j 3.3.0 ========
2017-10-31 15:50:26.279+0000 INFO  Starting...
2017-10-31 15:50:28.849+0000 INFO  Bolt enabled on 127.0.0.1:7687.
2017-10-31 15:50:34.056+0000 INFO  Started.
2017-10-31 15:50:35.693+0000 INFO  Remote interface available at http://localhost:7474/

可以看到配置文件位置:/etc/neo4j,找到並去掉該句注釋#dbms.connectors.default_listen_address=0.0.0.0,實現遠程訪問。
重新啟動,然后在瀏覽器輸入:http://server_ip:7474/即可訪問。
neo4j
驚不驚喜,激不激動!反正我心好累啊...因為我好迷茫...密碼又是啥啊!!!默認密碼是neo4j
在試了不加密碼和'neo4j'以后,又在網上找到了不需要密碼的方法,去掉#dbms.security.auth_enabled=false的注釋然鵝還是登!錄!不!進!去!
后來看瀏覽器控制台報錯,終於發現好像是ip:7687這個網址連接不上……好吧,又開了一個端口號,終於可以登錄了,凌晨一點多了,要哭了好嗎……說好的早睡呢……
打開之后是萬年不變的Hello World:
HelloWorld

清空數據庫

文件存儲位置:/var/lib/neo4j/datadatabases/graph.db
直接全部刪除:rm -rf /var/lib/neo4j/datadatabases/graph.db

2. 基礎概念

Neo4j是一個NoSQL圖形數據庫。和SQL比,能更好的表現出數據之間的關系。Neo4j中記錄和關系有同等重要的地位。可以簡潔高效的查出節點之間的關系。

節點(Nodes):一個節點就是圖形數據庫的一條記錄。在圖中以一個圓圈的形式表現。

關系(Relationships):關系用來連接節點,一個關系連接兩個節點。關系是有向的,連接的點分為源點和目標點。不同的節點可以通過關系連接起來。(同一個節點也可以有關系,自環。)但是一個關系有且只能有一個類型(Types)。在圖中是連接圓圈的邊。

屬性(Properties):圖形數據庫中數據作為屬性存在節點中。屬性為鍵值對形式,一個節點可以有多個屬性。關系也可以擁有屬性。每一個節點或屬性都有一個integer類型的默認屬性id,用來唯一標識節點/屬性。

標簽(Labels):用來標識一個節點屬於哪一類。一個節點可以有多個或0個標簽。標簽沒有屬性。(比如博客每一篇文章都有添加標簽選項,當寫一篇Java操作Neo4j的文章,可能會添加JavaNeo4j兩個標簽,當查看關於Java的文章時,可以通過標簽Java快速搜索。也有點類似於接口,但是標簽沒有屬性,類似於沒有內容的接口>_<)

路徑(Path):看圖很好理解,就是從一個節點出發經過一些關系和節點之后,到達某個節點的全部過程。一個路徑看起來是(node)-[relation]-...-(node)這樣子的。單獨一個節點也可以看做是一個長度為0的路徑。

可以通過``(反單引號)將標簽或屬性名括起來防止和關鍵字沖突。

3. Cypher

Cypher是Neo4j的圖形查詢語言,關鍵字大小寫不敏感。(大寫打起來太麻煩了 一律用小寫...)語法和SQL很像,學起來相對簡單。

基本格式:
MATCH <pattern> WHERE <conditions> RETURN <expressions>
() 表示節點
[] 表示關系
{} 表示節點的屬性,每個屬性通過key:value的形式表示,多個屬性之間用逗號隔開
node:label1:label2 通過冒號給節點添加標簽,通過冒號分隔多個標簽
數據類型:
boolean:true/false
integer:64位整數
float:64位浮點數
String:Unicode字符串
[]:表示數組

節點相關操作

  • 節點
    () 表示一個最簡單的節點,沒有標簽和屬性。
    (:label1) 有一個標簽的節點
    (:label1:label2:label3) 有多個標簽的節點
    (:label1 {prop1:value1}) 有一個屬性的節點
    (:label1 {key1:value1,key2:value2}) 有一個標簽和節點
    (nodeName:label1 {key1:value1}) 這里可以給node起一個別名,但是,這只是一個別名,和節點本身無關,是一個變量,用於后續語句操作該節點,而不是節點的名字。

  • 新增
    新增的關鍵字是CREATE

    create (:女:成年:教師{age:28,name:'劉一'}); // 新增一個有三個標簽 兩個屬性的節點
    create (N:男:成年:醫生{age:32,name:'陳二'}) return N; // 創建一個節點並返回
    

    創建節點時將自動為節點生成一個idid是唯一且遞增的。

  • 查找
    查找的關鍵詞是MATCHWHERE
    match可以用來匹配模式和簡單匹配數據,where用來限定條件。通過.來引用節點的屬性Node.PropertyKey,可以同時查詢多個節點並返回。

    match(n) return n;      // 不設條件 查詢數據庫所有節點
    match(n:男{age:32}) return n;       // 匹配標簽有'男'且含有屬性age=32的節點
    match(n) where n.age<30 return n;   // 查詢屬性age<30的節點
    match(n), where id(n)=1 return n;    // 通過id查詢節點
    match(n),(m:女) where id(n)=20 return n,m;  // 同時查詢多個節點,當n,m都存在的時候才返回
    
  • 修改
    修改的關鍵字為SET
    格式:
    修改節點屬性:{{ 查詢語句 }} set n.propertKey=newValue;
    添加節點標簽:{{ 查詢語句 }} set n:<label>

    match(n{age:32}) set n.age=33; // 將所有age=32的節點的age屬性改為33
    match(n) where id(n)=1 set n.age=33 return n; // 將所有age=32的節點的age屬性改為33 並返回修改后的節點
    match(n) where id(n)=20 set n:神經病 return n; // 為節點添加一個標簽<神經病>
    
  • 刪除
    刪除關鍵詞:DELETE,REMOVE
    DELETE:刪除節點,格式:DELETE <node>
    REMOVE:刪除節點或關系的標簽或屬性,格式:REMOVE node.propertyKeyREMOVE node:label

    match(n) where id(n)=23 delete n;   // 刪除一個節點
    match(n) where id(n)=20 remove n:`神經病` return n; // 刪除標簽
    match(n) where id(n)=20 remove n.age return n;  // 刪除屬性
    

    當一個節點有關聯關系的時候,是不能被刪除的,必須要先刪除相關關系。

    match (n) where id(n)=40 detach delete n;   // 刪除一個節點相關關系 然后刪除該節點
    

關系相關操作

  • 關系
    -- 無向關系
    <----> 有向關系
    -[:type]-> 表示一個類型為type的關系
    -[:type {key1:value1,key2:value2}] 關系也可以有一個或多個屬性。
    -[rel:type {key1:value1,key2:value2}] 同節點,這里rel只是關系的一個別名而已。
    創建關系時必須有方向,關系也必須有且只有一個類型。

關系的操作和節點相仿。

  • 新增

    match (n{name:'劉一'}),(m{name:'陳二'}) create (m)-[r:love]->(n) return type(r); // 找到兩個節點並創建類型為`love`的關系,返回關系類型。
    create (n1:N{name:'first'})-[r1:R]->(n2:N{name:'second'})<-[r2:R]-(n3:N{name:'third'}) return n1,r1,n2,r2,n3; // 創建了三個節點兩個關系
    
  • 查找
    單獨返回關系並沒有返回結果,可以選擇一起返回關系及關系相關節點,或者返回路徑。

    match ()-[r]-() where id(r)=13 return r;
    match (n)-[r]-(m) where n.name='劉一' and m.name='陳二' return n,r,m;   // where中多個查詢條件用and連接 表示與關系
    match p=(n)-[r]-(m) where n.name='劉一' and m.name='陳二' return p;   // 查詢路徑
    
  • 修改

    match ()-[r]-() where id(r)=2 set r.reason=['fairness','cute','comely','gorgeous']; // 為關系新增了一個屬性`reason`,屬性值是一個數組。
    match p=()-[r]-() where id(r)=2 set r.reason='no reason!' return p; // 又將`reason`屬性修改為字符串
    
  • 刪除
    remove 刪除屬性、delete 刪除關系

    match p=()-[r]-() where id(r)=2 remove r.reason return p; // 刪除關系屬性
    match p=()-[r]-() where id(r)=2 delete r;
    

    刪除所有節點&關系: match (n) detach delete n;

Merge子句

Merge子句的作用有兩個:當模式(Pattern)存在時,匹配該模式;當模式不存在時,創建新的模式,功能是match子句和create的組合。在merge子句之后,可以顯式指定on creae和on match子句,用於修改綁定的節點或關系的屬性。

  • 簡單匹配或創建
    merge (n:狗{name:'dog'}) return n 將創建並返回節點'dog'
    merge (n:狗{name:'dog'}) return n 返回已存在節點'dog'
  • on create 如果是創建則執行
    merge (n:狗{name:'dog1'}) on create set n.create=timestamp() return n 如果是新創建的節點就設置create屬性,timestamp()函數返回當前時間,類型為integer。
  • on match 如果已存在則執行該子句
    merge (n:狗{name:'dog'}) on match set n.update=timestamp() return n
  • 可以同時指定on createon match
    merge (n:狗{name:'dogx'}) on create set n.version=0 on match set n.version=n.version+1 return n.version

查詢語句

清空數據庫,然后插入十條語句。並創建一些關系,用於后續查詢。
原諒我膚淺,只能想出這種數據……(捂臉)

MATCH (n) DETACH DELETE n

CREATE 
(N1:女:成年:教師{age:28,name:'劉一',interest:['shopping','reading']}),
(N2:男:成年:醫生{age:28,name:'陳二',interest:['football']}),
(N3:女:未成年:學生{age:17,name:'張三',interest:['games']}),
(N4:男:成年:教師{age:23,name:'李四',interest:['reading']}),
(N5:女:成年:醫生{age:25,name:'王五',interest:['reading']}),
(N6:男:未成年:學生{age:13,name:'趙六'}),
(N7:女:成年:程序員{age:36,name:'孫七'}),
(N8:男:成年{age:68,name:'周八'}),
(N9:女:未成年:學生{age:16,name:'吳九'}),
(N10:男:未成年{age:15,name:'鄭十'}),
(N1)-[:love]->(N2)<-[:love]-(N3),
(N4)-[:know]->(N5),
(N4)-[:know]->(N6),
(N5)-[:know]->(N7),
(N5)-[:know]->(N8),
(N6)-[:know]->(N7),
(N7)-[:know]->(N8),
(N9)-[:hate]->(N8)
  • 常用謂詞
    and表示查詢條件與關系,or表示或關系,xnot表示異或,not表示非。
    查詢年齡在[15,25]之間的女生:match (n:女) where n.age>=15 and n.age<=25 return n
    查詢年齡不大於18的人:match (n) where not n.age>18 return n

  • 其他常用關鍵詞
    distinct 表示查詢去掉重復 有些查詢在圖形中表示不出來,需要到Table中查看查詢結果。
    查詢所有人的年齡,並且去掉重復:match (n) return distinct n.age
    order by表示排序,默認升序。
    查詢所有人按年齡排序:match (n) return n order by n.age desc
    skip表示忽略前面一定數量,limit表示查詢數量。
    查看年齡最大的五個人:match (n) return n order by n.age skip 5 limit 5
    關鍵字in表示是否包含在數組中。
    查詢名字為'張三','李四','王五'的人:match (n) where n.name in ['張三','李四','王五'] return n
    查詢喜歡閱讀的人:match (n) where 'reading' in n.interest return n

  • 聚合函數
    count(),min(),max(),avg(),sum(),collect()
    查詢年齡的平均值:match (n) return avg(n.age)
    查詢學生數量:match (n:學生) return count(n)
    查詢並返回所有人的集合:match (n) return collect(n)

  • 常用函數
    keys(node)/keys(relationship)查看節點或關系的屬性鍵。
    查詢屬性:match (n)-[r]-() return keys(n), keys(r)
    properties(node)/properties(relationship)查看的是屬性鍵值對。
    查詢屬性值:match (n)-[r]-() return properties(n), properties(r)
    exists()查詢屬性是否存在
    查詢存在interest屬性的節點:match (n) where exists(n.interest) return n
    labels(node)函數返回節點的標簽集合
    查詢不是程序程序員的成年人:match (n) where '成年' in labels(n) and not '程序員' in labels(n) return n;
    nodes(path)查詢路徑相關節點,relationships(path)查詢路徑相關關系。
    返回路徑中的節點:match p=()-[:love]->()<-[:love]-() return nodes(p);
    startNode()endNode() 查看關系的起止節點。
    查看男女之間的關系(哪里奇怪?):match p=(:男)-[r]-(:女) return startNode(r).name, endNode(r).name;

  • 查詢路徑
    [*]表示不限制路徑的長度。length(path)查詢一條路徑長度。
    查詢李四周八的所有路徑:match p=({name:'李四'})-[*]-({name:'周八'}) return p, length(p)
    [*n]距離為n, [*..n]最大距離為n,[*n..]最小距離為n,[*m..n]距離在m到n之間。
    查詢李四周八長度為2的路徑:match p=({name:'李四'})-[*2]-({name:'周八'}) return p
    查詢最短路徑shortestPath
    查詢李四周八之間最短的路徑:match (n{name:'李四'}) match (m{name:'周八'}) return shortestPath((n)-[*]-(m)) as p

  • 字符串匹配
    starts with, end with, contains
    查詢名字以'一'結束的節點:match (n) where n.name ends with '一' return n
    正則表達式=~
    也可以通過正則表達式查詢:match (n) where n.name =~ '.一' return n

  • WITH 子句
    可以實現子查詢,隨便舉個例子,查詢版本姓名的xxx的年齡最大的人

match (n:people) 
where n.name='xxx' 
with max(n.age) as mage 
match (m:people) 
where m.name='xxx' and m.age = mage 
return m;


免責聲明!

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



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