Neo4j模塊
存儲結構
節點存儲
節點是否可用+最近一個關係的Id(-1表示無)+最近一個屬性的Id(-1表示無) Node[0,used=true,rel=9,prop=-1] Node[1,used=true,rel=1,prop=0] Node[2,used=true,rel=2,prop=2] Node[3,used=true,rel=2,prop=4] Node[4,used=true,rel=4,prop=6] Node[5,used=true,rel=5,prop=8] Node[6,used=true,rel=5,prop=10] Node[7,used=true,rel=7,prop=12] Node[8,used=true,rel=8,prop=14] Node[9,used=true,rel=8,prop=16] Node[10,used=true,rel=10,prop=18] Node[11,used=true,rel=11,prop=20] Node[12,used=true,rel=11,prop=22]
關係存儲
是否可用+關係的頭節點+關係的尾節點+關係類型+頭節點的前一個關係Id+頭節點的後一個關係id+尾節點的前一個關係Id+尾節點的後一個關係Id+關係的最近屬性Id Relationship[0,used=true,source=1,target=0,type=0,sPrev=1,sNext=-1,tPrev=3,tNext=-1,prop=1] Relationship[1,used=true,source=2,target=1,type=1,sPrev=2,sNext=-1,tPrev=-1,tNext=0,prop=3] Relationship[2,used=true,source=3,target=2,type=2,sPrev=-1,sNext=-1,tPrev=-1,tNext=1,prop=5] Relationship[3,used=true,source=4,target=0,type=0,sPrev=4,sNext=-1,tPrev=6,tNext=0,prop=7] Relationship[4,used=true,source=5,target=4,type=1,sPrev=5,sNext=-1,tPrev=-1,tNext=3,prop=9] Relationship[5,used=true,source=6,target=5,type=2,sPrev=-1,sNext=-1,tPrev=-1,tNext=4,prop=11] Relationship[6,used=true,source=7,target=0,type=0,sPrev=7,sNext=-1,tPrev=9,tNext=3,prop=13] Relationship[7,used=true,source=8,target=7,type=1,sPrev=8,sNext=-1,tPrev=-1,tNext=6,prop=15] Relationship[8,used=true,source=9,target=8,type=2,sPrev=-1,sNext=-1,tPrev=-1,tNext=7,prop=17] Relationship[9,used=true,source=10,target=0,type=0,sPrev=10,sNext=-1,tPrev=-1,tNext=6,prop=19] Relationship[10,used=true,source=11,target=10,type=1,sPrev=11,sNext=-1,tPrev=-1,tNext=9,prop=21] Relationship[11,used=true,source=12,target=11,type=2,sPrev=-1,sNext=-1,tPrev=-1,tNext=10,prop=23]
屬性存儲
是否可用+前一個屬性Id+後一個屬性Id+屬性塊32個字節 Property[10,used=true,prev=-1,next=9,PropertyBlock[INT,key=7,value=5]]
文件結構
- 節點和關係存儲文件只關心圖的基本存儲結構而不是屬性數據,這兩種記錄都是固定大小,從而達到高性能遍歷的關鍵設計決策.節點記錄和關係記錄都是相當輕量級的,由指向聯繫和屬性列表的指針構成
- 一個節點的所有屬性被記錄到一個單向鏈表上面.只有指向下一個屬性的指針,沒有指向上一個屬性的指針
- 兩個節點之間的所有關係被記錄到一個雙向鏈表上面,既有指向上一個關係的指針,也有指向下一個關係的指針
- 節點存儲文件和關係存儲文件都是固定長度,只關心結構,不關心屬性數據,屬性存儲文件也是固定長度,只關心數據,不關心結構.當長度不足時,會去申請動態存儲,將超出的數據長度存放在動態存儲裏面,並將地址存放在屬性存儲文件中.查找的時候進行拼接
性能測試
測試環境:
1. 操作系統: Mac OS X 10.10.5
2. 內存: 8G
3. CPU參數: 8核8線程
4. 編程語言: python 2.7
5. Neo4j 版本: 3.3.0
6. 服務器節點數: 單點
測試內容: 節點數分別在1萬, 10萬, 100萬,1000萬情況下,在節點設置索引和不設置索引的情況下查找節點的平均延時。測試結果如下:
7.1000萬節點的情況下有索引和無索引插入延時測試:
查詢優化策略
- Neo4j HA:(High Availability)即 neo4j 的高可用特性(不過這個特徵只能在neo4j 企業版中可用,手動搭建需要自己進行).
- 增加緩存:通過修改配置文件中dbms. query_ cache_ size參數進行調整.
- 索引查詢優化
- Neo4j和KV(Key-Value)數據庫聯合使用:通常在圖庫和 KV 數據庫聯合使用時, 特別是經常需要通過屬性來查詢實體時需要設置 neo4j schema Index,即將neo4j中與 KV 數據庫關聯的值設置索引。
查詢語法Cypher
https://blog.csdn.net/qq_37242224/article/details/81325625
https://neo4j.com/developer/guide-sql-to-cypher/
SELECT p.ProductName, p.UnitPrice FROM products as p ORDER BY p.UnitPrice DESC LIMIT 10;
MATCH (p:Product) RETURN p.productName, p.unitPrice ORDER BY p.unitPrice DESC LIMIT 10;
運算符
- 數學運算符:+、-、*、/、%、^
- 比較運算符:=、<>、<、>、<=、>=、IS NULL、IS NOT NULL
- 布爾運算符:AND、OR、XOR、NOT
- 字符串運算符:+、=~
- 列表運算符:+、IN
語句
- 讀語句:MATCH、OPTIONAL MATCH、WHERE、START、Aggregation、LOAD CSV
- 寫語句:CREATE、MERGE、SET、DELETE、REMOVE、FOREACH、CREATE UNIQUE
- 通用語句:RETURN、ORDER BY、LIMIT、SKIP、WITH、UNWIND、UNION、CALL
- 字符串匹配:STARTS WITH、ENDS WITH、CONTAINS
函數
- 斷言函數all、any、none、single、exists
- 標量函數size、length、type、id、coalesce
- 列表函數
- 數學函數
- 字符串函數
- 自定義函數
LOAD CSV
檢索架構
一、有大量存量數據(億級以上)(並長期有增量數據進入)
1、使用NEO4J + ELASTICSEARCH(Neo4j提供ES插件,類似還有Apache Spark、MongoDB、Cassandra插件等)
二、無大量存量數據或者少量存量數據(或全部爲增量數據)
1、建立全文檢索之後,設置索引同步更新即可(對於大量數據的索引重建比較費時)。
2、建立全文檢索之後(使用自定義支持中文的全文索引過程),設置增量入庫數據同步更新到索引即可(索引的重建如果做不好優化將會比較費時)。
應用集成
<!--neo4j--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-neo4j</artifactId> </dependency>
可視化界面