下載地址: https://neo4j.com/download/
相關API參考: https://www.w3cschool.cn/neo4j/
1. 簡介
圖數據庫主要用於存儲更多的連接數據。如果我們使用 RDBMS 數據庫來存儲更多連接的數據,那么它們不能提供用於遍歷大量數據的適當性能。 在這些情況下,Graph Database 提高了應用程序性能。
(1) 特點
SQL就像簡單的查詢語言Neo4j CQL
它遵循屬性圖數據模型
它通過使用Apache Lucence支持索引
它支持UNIQUE約束
它包含一個用於執行CQL命令的UI:Neo4j數據瀏覽器
它支持完整的ACID(原子性,一致性,隔離性和持久性)規則
它采用原生圖形庫與本地GPE(圖形處理引擎)
它支持查詢的數據導出到JSON和XLS格式
它提供了REST API,可以被任何編程語言(如Java,Spring,Scala等)訪問
它提供了可以通過任何UI MVC框架(如Node JS)訪問的Java腳本
它支持兩種Java API:Cypher API和Native Java API來開發Java應用程序
(2) 優點
它很容易表示連接的數據 檢索/遍歷/導航更多的連接數據是非常容易和快速的 它非常容易地表示半結構化數據 Neo4j CQL查詢語言命令是人性化的可讀格式,非常容易學習 使用簡單而強大的數據模型 它不需要復雜的連接來檢索連接的/相關的數據,因為它很容易檢索它的相鄰節點或關系細節沒有連接或索引
neo4j中的主要組成部分:節點(node),關系(relationship),屬性(property),標簽(label)
節點:一個圖形的一個基本單元,表示一個實體
屬性:節點和關系都可擁有屬性,表示為一個鍵值對,鍵名為字符串,值可以是數字,布爾值,字節,字符串,字符串數組,日期。
關系:連接兩個節點,包含一個開始節點和一個尾節點。
標簽:Label將一個公共名稱與一組節點或關系相關聯。 節點或關系可以包含一個或多個標簽。 我們可以為現有節點或關系創建新標簽。 我們可以從現有節點或關系中刪除現有標簽。
2. Cypher 查詢簡介
Neo4j CQL支持以下數據類型:
1. boolean 用於表示布爾文字:true,false。 2. byte 用於表示8位整數。 3. short 用於表示16位整數。 4. int 用於表示32位整數。 5. long 用於表示64位整數。 6. float I用於表示32位浮點數。 7. double 用於表示64位浮點數。 8. char 用於表示16位字符。 9. String 用於表示字符串。
Neo4j CQL命令/條款:
1。 CREATE 創建 創建節點,關系和屬性 2。 MATCH 匹配 檢索有關節點,關系和屬性數據 3。 RETURN 返回 返回查詢結果 4。 WHERE 哪里 提供條件過濾檢索數據 5。 DELETE 刪除 刪除節點和關系 6。 REMOVE 移除 刪除節點和關系的屬性 7。 ORDER BY 以…排序 排序檢索數據 8。 SET 組 添加或更新標簽
Neo4j CQL 函數:
1。 String 字符串 它們用於使用String字面量。 2。 Aggregation 聚合 它們用於對CQL查詢結果執行一些聚合操作。 3。 Relationship 關系 他們用於獲取關系的細節,如startnode,endnode等。
3. 安裝
前提是要先安裝JDK,注意JDK版本也有關系,我之前的JDK是11,然后neo4j 服務可以注冊成功,但是啟動失敗,所以需要切換JDK為8
(1) 到https://neo4j.com/download/ 下載安裝包
我下載的是社區版: neo4j-community-3.5.5
(2) 安裝neo4j 服務 - 到neo4j 的安裝目錄
neo4j.bat install-service
(3) 啟動服務
neo4j.bat console
4.Neo4J使用
Neo4J提供了一個用戶友好的web界面,可以進行各項配置、寫入、查詢等操作,並且提供了可視化功能。類似ElasticSearch一樣。
打開瀏覽器,輸入 http://127.0.0.1:7474/browser/ 接下來登錄進去即可,默認的賬號密碼都是:neo4j。 首次登錄之后需要修改密碼, 例如我的密碼修改為neo4j.
5. 練習
neo4j 也會為每個節點分配一個id 屬性,類似於MongoDB 生成的docId 屬性,自動遞增,Id屬性的最大值約為35億。
這里我們建立兩種類型的節點: Group 代表班級, Student 代表學生, 其中主要人物關系如下:
Group: 包含一個節點,name為 "宏哥班", num 編號為 "298"
Student: 包含六個學生,name 分別為:(神經、力超、旺懂、旺約、佩奇、畜生), 其中神經是女性,其他的為男性
人物關系和班級關系為:
(1) 除了畜生都屬於班級 298
(2) 力超、旺懂、旺約、佩奇 都LIKES 神經, 神經LIKES 力超, 但是 神經和畜生 MARRIED
1. 清除所有的節點
MATCH (n) DETACH DELETE n
2. 創建一個班級節點 (name為為 "宏哥班", 編號改為 "298")
創建班級節點,默認帶着name 屬性:
CREATE (n:Group {name:'宏哥班'}) RETURN n
可以看到生成一個班級節點:
修改班級: 增加num 屬性,和人數屬性:
MATCH (a:Group {name:'宏哥班'}) SET a.num = "298", a.total = 55
刪除班級節點人數屬性:
MATCH (a:Group {name:'Soft1'}) REMOVE a.total
3. 創建人物相關節點:
(1)先建立四個節點
CREATE (n:Student {name:'力超', sex: "男"}) RETURN n CREATE (n:Student {name:'旺懂', sex: "男"}) RETURN n CREATE (n:Student {name:'旺約', sex: "男"}) RETURN n CREATE (n:Student {name:'佩奇', sex: "男"}) RETURN n
(2) 然后建立 神經 和 畜生,並且建立married 關系
CREATE (a:Student {name:'畜生'})-[r:MARRIED]->(b:Student {name:'神經'})
反向建立關系:
MATCH (a:Student {name:'神經'}), (b:Student {name:'畜生'}) MERGE (a)-[:married]->(b)
此時關系圖如下:
(3) 建立 力超、旺懂、旺約、佩奇 和 神經的喜歡關系:
- 神經 LIKES 力超, 從2009 年開始, 到2015 年結束 (建立關系的時候給關系建立屬性)
MATCH (a:Student {name:'神經'}), (b:Student {name:'力超'}) MERGE (a)-[:LIKES {since:2009, end: 2015}]->(b)
- 力超 LIKES 神經, 從2012 年開始, 到2015 年結束
MATCH (a:Student {name:'力超'}), (b:Student {name:'神經'}) MERGE (a)-[:LIKES {since:2012, end: 2015}]->(b)
- 旺懂喜歡神經
MATCH (a:Student {name:'旺懂'}), (b:Student {name:'神經'}) MERGE (a)-[:LIKES]->(b)
- 旺約喜歡神經
MATCH (a:Student {name:'旺約'}), (b:Student {name:'神經'}) MERGE (a)-[:LIKES]->(b)
- 佩奇 喜歡 神經
MATCH (a:Student {name:'佩奇'}), (b:Student {name:'神經'}) MERGE (a)-[:LIKES]->(b)
- 畜生喜歡神經
MATCH (a:Student {name:'畜生'}), (b:Student {name:'神經'}) MERGE (a)-[:LIKES]->(b)
4. 建立人物和班級之間的關系
MATCH (a:Student {name:'神經'}), (b:Group {name:'宏哥班'}) MERGE (a)-[:BELONGTO{since: 2009, end: 2012}]->(b) MATCH (a:Student {name:'力超'}), (b:Group {name:'宏哥班'}) MERGE (a)-[:BELONGTO{since: 2009, end: 2012}]->(b) MATCH (a:Student {name:'旺懂'}), (b:Group {name:'宏哥班'}) MERGE (a)-[:BELONGTO{since: 2009, end: 2012}]->(b) MATCH (a:Student {name:'旺約'}), (b:Group {name:'宏哥班'}) MERGE (a)-[:BELONGTO{since: 2009, end: 2012}]->(b) MATCH (a:Student {name:'佩奇'}), (b:Group {name:'宏哥班'}) MERGE (a)-[:BELONGTO{since: 2009, end: 2012}]->(b)
人物關系和班級關系都已經建立完成。
5. 查詢
(1) 查詢此時的關系圖如下:
MATCH (n) RETURN n LIMIT 25
(2) 查詢298班的學生
MATCH (a:Student)-[:BELONGTO]->(b:Group {num: "298"}) RETURN a,b
(3) 查詢298班的學生,名稱為神經或者佩奇的
MATCH (a:Student)-[:BELONGTO]->(b:Group {num: "298"}) where a.name = "佩奇" or a.name = "神經" RETURN a,b MATCH (a:Student)-[:BELONGTO]->(b:Group {num: "298"}) where a.name in ["佩奇", "神經"] RETURN a,b
(4) 查詢298班的學生: 按名稱逆序排序,前面跳過2個,后面取2個, 類似於mysql 的limit 2, 2 從第三個開始,取兩個 (skip和limit 實現分頁)
MATCH (a:Student)-[:BELONGTO]->(b:Group {num: "298"}) RETURN a,b order by a.name desc skip 2 limit 2
(5) 查詢所有喜歡神經的學生:
MATCH (a:Student)-[:LIKES]->(b:Student {name: "神經"}) RETURN a,b
(6) 查詢所有喜歡神經的、並且班級是298班的學生:
MATCH (b:Student {name: "神經"})<-[:LIKES]-(a:Student)-[:BELONGTO]->(c:Group {num: "298"}) RETURN a,b,c
(7) 查詢旺懂喜歡的人喜歡的人: (旺懂 -> 神經 -> 力超)
MATCH (a:Student{name: "旺懂"})-[r1:LIKES]-> () -[r2:LIKES]-> (wangdong_likes_likes) RETURN wangdong_likes_likes
(8) 查詢所有對外有關系的節點
MATCH (a)-->() RETURN a
(9) 查詢所有有關系的節點:
MATCH (a)--() RETURN a
(10). 查詢所有對外有關系的節點,以及關系類型
MATCH (a)-[r]->() RETURN a.name, type(r)
(11) 查詢有結婚關系的人:
MATCH (n)-[:married]-() RETURN n
6. union/union all (將兩組結果中的公共行組合並返回到一組結果中/返回由兩個節點重復行) = 結果列類型和來自兩組結果的名稱必須匹配,這意味着列名稱應該相同,列的數據類型應該相同。
類似於Mysql 的union 和 union all
UNION子句語法: <MATCH Command1> UNION <MATCH Command2> UNION ALL子句語法: <MATCH Command1> UNION ALL <MATCH Command2>
7. 函數
===字符串函數
(1) UPPER 它用於將所有字母更改為大寫字母
(2) LOWER 它用於將所有字母改為小寫字母
(3) SUBSTRING 它用於獲取給定String的子字符串
(4) REPLACE 它用於替換一個字符串的子字符串
測試:
創建一個name 為 Alimi 的狗
create (n:Dog {name: 'Amili'}) return n
查詢Amili: name 轉為大寫
match(n:Dog) return upper(n.name)
====AGGREGATION聚合
和SQL一樣,Neo4j CQL提供了一些在RETURN子句中使用的聚合函數。 它類似於SQL中的GROUP BY子句。我們可以使用MATCH命令中的RETURN +聚合函數來處理一組節點並返回一些聚合值。
(1) COUNT 它返回由MATCH命令返回的行數。
(2) MAX 它從MATCH命令返回的一組行返回最大值。
(3) MIN 它返回由MATCH命令返回的一組行的最小值。
(4) SUM 它返回由MATCH命令返回的所有行的求和值。
(5) AVG 它返回由MATCH命令返回的所有行的平均值。
測試:
查詢Student 標簽包含的節點數量:
MATCH (e:Student) RETURN COUNT(*)
查詢喜歡神經的人數:
MATCH (a:Student)-[:LIKES]->(b:Student {name: "神經"}) RETURN count(a)
====關系函數
(1) STARTNODE 它用於知道關系的開始節點。
(2) ENDNODE 它用於知道關系的結束節點。
(3) ID 它用於知道關系的ID。
(4) TYPE 它用於知道字符串表示中的一個關系的TYPE。
- 查詢喜歡關系的結束節點:
MATCH (a)-[like:LIKES]->(b) RETURN ENDNODE(like)
- 查詢喜歡關系的結束節點:並且去重
MATCH (a)-[like:LIKES]->(b) RETURN distinct ENDNODE(like)
- 查詢喜歡關系的開始節點:
MATCH (a)-[like:LIKES]->(b) RETURN STARTNODE(like)
8. 索引
Create Index 創建索引
Drop Index 丟棄索引
為Student的name 列創建索引:
CREATE INDEX ON :Student (name)
為Student的name 列刪除索引:
DROP INDEX ON :Student (name)
查看索引與約束:
:schema
或者:
call db.indexes
9. 約束 (唯一約束自帶Index)
我們也可以創建唯一約束,避免創建多個重復的節點
學生Student的屬性name 建立唯一約束:
CREATE CONSTRAINT ON (n:Student) ASSERT n.name IS UNIQUE
查看約束:
再次插入一列進行測試:(報錯違反唯一約束)
刪除約束:
DROP CONSTRAINT ON (n:Student) ASSERT n.name IS UNIQUE
補充: 根據ID操作節點
根據ID刪除節點: MATCH (r) WHERE id(r) = 33 DELETE r RETURN r (有關系不能刪除,必須先刪除關系) MATCH (r) WHERE id(r) = 33 DETACH DELETE r RETURN r 級聯刪除, 有關系存在也可以刪除 根據ID修改節點: 將畜生name 改為姓趙的畜生 MATCH (r) WHERE id(r) = 32 SET r.name = "姓趙的畜生" 根據ID查詢姓趙的畜生 MATCH (r) WHERE id(r) = 32 RETURN r
(1) MATCH語句用於指定的模式檢索數據庫;OPTIONAL MATCH語句用於搜索模式中描述的匹配項,對於找不到的項,用null代替;在Cypher語句中,類似於SQL語句中的outer join
(2) NEO4J中WITH的用法: 此子句用於將查詢部分鏈接在一起。將其中一個部分的結果輸送到下一個部分中作為起點或條件。
例如查詢喜歡神經的並且name 為佩奇的:
MATCH (a:Student)-[:LIKES]->(b:Student {name: "神經"}) with a,b where a.name = "佩奇" RETURN a,b
補充: Neo4j中的case 語句
neo4j也有 case 語句, 類似於MySQL的case 語句.例如:將學生 Student 的性別轉為數字表示的 性別
MATCH (n:Student) RETURN n.name, CASE n.sex WHEN '男' THEN 1 WHEN '女' THEN 2 ELSE '未知' END AS result
結果:
補充:neo4j別名
neo4j 查詢出來起個別民:
MATCH (a:Student) WHERE a.name = "佩奇" RETURN a.name, a.sex
補充:neo4j也有 case 語句, 類似於MySQL的case 語句
例如:將學生 Student 的性別轉為數字表示的 性別
MATCH (n:Student) RETURN n.name, CASE n.sex WHEN '男' THEN 1 WHEN '女' THEN 2 ELSE '未知' END AS result
結果:
補充:neo4j 查詢出來起個別名:
MATCH (a:Student) WHERE a.name = "佩奇" RETURN a.name, a.sex
補充: merge 命令
MERGE命令: 創建節點,關系和屬性;為從數據庫檢索數據
MERGE命令是CREATE命令和MATCH命令的組合。 MERGE = CREATE + MATCH。 Neo4j CQL MERGE命令語法與CQL CREATE命令類似。
Neo4j CQL MERGE命令在圖中搜索給定模式,如果存在,則返回結果;如果它不存在於圖中,則它創建新的節點/關系並返回結果。 merge 創建關系或者節點都可以用create 替代。測試如下:
MERGE 語法如下:
MERGE (<node-name>:<label-name> { <Property1-name>:<Pro<rty1-Value> ..... <Propertyn-name>:<Propertyn-Value> })
比如上面我們可以將神經和佩奇建立likes 關系也可以用create, 例如:
match(a:Student{name: "神經"}), (b:Student{name: "佩奇"}) merge (a) -[:LIKES]->(b) return a,b
然后刪除這個關系:
match(a:Student{name: "神經"}) -[r:LIKES]-> (b:Student{name: "佩奇"}) delete r
用create 建立關系:
match(a:Student{name: "神經"}), (b:Student{name: "佩奇"}) create (a) -[:LIKES]->(b) return a,b
比如用merge 創建一個節點:
create (a:Dog{name: 'zs'}) // 多次執行會創建多個節點 merge (a:Dog{name: 'zs'}) // 不會創建節點 merge (a:Dog{name: 'zs1'}) // 會創建節點,也就是在節點存在的情況下不會創建節點。 相當於match + create, 先match 匹配,不存在進行create操作
補充: neo4j 也可以多條語句同時執行
neo4j 也可以支持多條語句同時執行, 用分號分割即可。比如:
CREATE INDEX ON :STUDENT (NAME);
CREATE INDEX ON :PERSON (NAME);
也可以建立點的時候建立關系,比如:
merge (a:student{name: '張三'}) set a.sex = '男' merge (b:student{name: '李四'}) set b.sex = '女' MERGE (a)-[:LIKE]->(b)