Neo4j基本入門
Neo4j
是一個高性能的,NOSQL
圖形數據庫,它將結構化數據存儲在網絡上而不是表中。它是一個嵌入式的、基於磁盤的、具備完全的事務特性的Java
持久化引擎,但是它將結構化數據存儲在網絡(從數學角度叫做圖)上而不是表中。Neo4j
也可以被看作是一個高性能的圖引擎,該引擎具有成熟數據庫的所有特性。程序員工作在一個面向對象的、靈活的網絡結構下而不是嚴格、靜態的表中——但是他們可以享受到具備完全的事務特性、企業級的數據庫的所有好處。
一、基本概念

1. 標簽(Label)
在Neo4j
中,一個節點可以有一個以上的標簽,從現實世界的角度去看,一個標簽可以認為節點的某個類別,比如BOOK
、MOVIE
等等。
2. 節點(Node)
節點是指一個實實在在的對象,這個對象可以有好多的標簽,表示對象的種類,也可以有好多的屬性,描述其特征,節點與節點之間還可以形成多個有方向(或者沒有方向)的關系。
3. 關系(Relationship)
用來描述節點與節點之間的關系,這也是圖數據與與普通數據庫最大的區別,正是因為有這些關系的存在,才可以描述那些我們普通行列數據庫所很難表示的網狀關系,比如我們復雜的人際關系網,所謂的六度理論,就可以很方便的用圖數據庫進行模擬,比如我們大腦神經元之間的連接方式,都是一張復雜的網。
有一點需要重點注意,關系可以擁有屬性。
4. 屬性(Property)
描述節點的特性,采用的是Key-Value
結構,可以隨意設定來描述節點的特征。
二、查詢語法(CQL)
序號 | 關鍵字 | 關鍵字作用 |
---|---|---|
1 | CREATE | 創建 |
2 | MATCH | 匹配 |
3 | RETURN | 加載 |
4 | WHERE | 過濾檢索條件 |
5 | DELETE | 刪除節點和關系 |
6 | REMOVE | 刪除節點和關系的屬性 |
7 | ORDER BY | 排序 |
8 | SET | 添加或更新屬性 |
1. 基本查找match return
neo4j
使用的查詢語法是Cypher
語法與我們常用的SQL查詢語法不一樣,但是在初步的學習之后,覺得他們之間使用的思路有很多重疊的地方,整個語句的執行流程也和SQL有比較多相似的地方。
# 創建兩個節點,一個子節點(Mask),一個父節點(Old_mask),他們之間是屬於父子關系
# 其中create表示新建
# p 表示這個節點的別名
# PERSON 表示節點p的標簽PERSON的屬性
# {} 大括號中間的鍵值對,表示p這個節點作為PERSON這個標簽類別所擁有的屬性
# -[r:SON_OF]-> 表示節點p指向節點f,他們之間的關系是SON_OF,這個關系的別名是r,r可以擁有屬於自己的屬性
# return 表示執行這段語句之后,需要返回的對象,return p,r,f 表示返回 節點p,節點f,以及他們之間的關系r
create(p:PERSON {name:"Mask",age:30,heigh:180,weight:80})-[r:SON_OF]->(f:PERSON {name:"OLD_Mask",age:55,heigh:160,weight:60}) return p,r,f

返回數據:

2. 查找指定節點、指定屬性、指定關系的節點、關系
# MATCH 匹配命令
# return 后面的別名p還可以利用as 設置指定的返回值名稱,如 p as userName
match (p:PERSON {name:"Mask"})-[r]-(n) return p,r,n
命令執行結果:


where
關鍵字類似於SQL
里面的where
關鍵字,可以通過運算符== >= ...
來過濾一些查詢條件。
3. 對查找結果進行排序order by,並限制返回條數 limit
order by
關鍵字與SQL
里面是一樣的操作,后面跟上需要根據排序的關鍵字,limit
的操作是指定輸出前幾條
# 這里利用order by來指定返回按照Person.name來排序
# limit 表示只返回前3條數據
match(p:Person) return p order by p.name limit 3
查找結果:

4. 刪除節點delete命令
刪除節點的操作也是通過dlete來操作,如果被刪除的節點存在Relationship,那么單獨刪除該節點的操作會不成功,所以如果想刪除一個已經存在關系的節點,需要同時將關系進行刪除。
刪除一個不存在Relationship節點,會報錯:

刪除一個節點記憶與他有關的關系,成功:

# 刪除指定條件的節點
# 先通過匹配關鍵字match找到匹配元素,然后通過delete關鍵字指定刪除
match(p:PERSON {name:"teacher_wange"}) delete p
# 刪除節點和節點相關的關系
match (p:Person {name:"lisi"})-[r]-() delete p,r
5. 刪除屬性remove命令
remove命令是用來刪除節點或者關系的屬性
刪除屬性前的節點:

刪除birthday
屬性后的節點:

6. neo4j的字符串函數
upper
,lower
,substring
,replac
四種字符串的操作,其中upper
與lower
在將來的版本中會被修改為toupper
/tolower
大寫轉換操作結果:

7. 聚合函數AGGREGATION
常用的聚合函數有COUNT
、MAX
、MIN
、AVG
、SUM
等五種。
match(p:Person) return p.name as name,p.age as age,count(p) as count,max(p.age) as maxAge,min(p.age) as minAge,avg(p.age) as avgAge,sum(p.age) as sumAge
聚合函數操作結果:

8. 關系函數
序號 | 函數名 | 函數功能描述 |
---|---|---|
1 | STARTNODE | 查找關系的起始點 |
2 | ENDNODE | 查找關系的終點 |
3 | ID | 查找關系的ID |
4 | TYPE | 查找關系的類型,也就是我們在圖表中看到的名稱 |
# 先獲取關系,然后通過關系函數來獲取關系的id、type、起始節點、終止節點等等信息
match ()-[r:SON_OF]-() return startnode(r).name as start_node, endnode(r).name as end_node,id(r) as relationship_id ,type(r) as realtionship_type
關系查詢結果:

在Java中使用
1. 原生的Neo4j Java API
Neo4j Java API
的設計思路及基本概念:
- Label接口,表示標簽,實現這個接口的類,就可以當標簽使用;
- Relationship接口,別是關系,實現這個接口的類,就可以表示關系;
- 通過
GraphDatabaseFactory
這個類的實例化對象可以獲取GraphDatabaseService
實例; GraphDatabaseService
實例對象,可以獲取一個操作事務,通過這個事務可以實現任何操作異常的回滾,操作成功需要調用tx.success()
方法;GraphDatabaseService
對象可以創建節點node
;- 節點
node
可以設置屬性setProperty(key,value)
; - 節點
node
可以創建關系Relationship
,Relationship
也可以通過setProperty(key,value)
來設置屬性;
枚舉標簽Label
package com.tp.ne4oj.java.examples;
import org.neo4j.graphdb.Label;
public enum Tutorials implements Label {
JAVA,SCALA,SQL,NEO4J;
}
枚舉關系Realationship
package com.tp.neo4j.java.examples;
import org.neo4j.graphdb.RelationshipType;
public enum TutorialRelationships implements RelationshipType{
JVM_LANGIAGES,NON_JVM_LANGIAGES;
}
獲取操作對象
GraphDatabaseFactory dbFactory = new GraphDatabaseFactory();
GraphDatabaseService db= dbFactory.newEmbeddedDatabase("C:/TPNeo4jDB");
啟動neo4j數據庫事務
try (Transaction tx = graphDb.beginTx()) {
// Perform DB operations
tx.success();
}
整體代碼
package com.tp.neo4j.java.examples;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
public class Neo4jJavaAPIDBOperation {
public static void main(String[] args) {
GraphDatabaseFactory dbFactory = new GraphDatabaseFactory();
GraphDatabaseService db= dbFactory.newEmbeddedDatabase("C:/TPNeo4jDB");
try (Transaction tx = db.beginTx()) {
Node javaNode = db.createNode(Tutorials.JAVA);
javaNode.setProperty("TutorialID", "JAVA001");
javaNode.setProperty("Title", "Learn Java");
javaNode.setProperty("NoOfChapters", "25");
javaNode.setProperty("Status", "Completed");
Node scalaNode = db.createNode(Tutorials.SCALA);
scalaNode.setProperty("TutorialID", "SCALA001");
scalaNode.setProperty("Title", "Learn Scala");
scalaNode.setProperty("NoOfChapters", "20");
scalaNode.setProperty("Status", "Completed");
Relationship relationship = javaNode.createRelationshipTo
(scalaNode,TutorialRelationships.JVM_LANGIAGES);
relationship.setProperty("Id","1234");
relationship.setProperty("OOPS","YES");
relationship.setProperty("FP","YES");
tx.success();
}
System.out.println("Done successfully");
}
}
Cypher執行引擎,讓Java執行原生CQL語句
package com.tp.neo4j.java.cql.examples;
import org.neo4j.cypher.javacompat.ExecutionEngine;
import org.neo4j.cypher.javacompat.ExecutionResult;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
public class JavaNeo4jCQLRetrivalTest {
public static void main(String[] args) {
// 1. 獲取graphDB
GraphDatabaseFactory graphDbFactory = new GraphDatabaseFactory();
GraphDatabaseService graphDb = graphDbFactory.newEmbeddedDatabase("C:/TPNeo4jDB");
// 2. 獲取Cypher執行引擎
ExecutionEngine execEngine = new ExecutionEngine(graphDb);
ExecutionResult execResult = execEngine.execute("MATCH (java:JAVA) RETURN java");
// 3. 獲取執行結果
String results = execResult.dumpToString();
System.out.println(results);
}
}
Spring Data neo4j 的操作
操作思路:
- 創建一個與圖數據庫存儲數據對應的實體類
entity
,並進行必要的注解; dao
層接口繼承Spring data Neo4j
類GraphRepository
、GraphTemplate
、CrudRepository
、PaginationAndSortingRepository
,這個和springDataJPA也比較類似;
基本導包操作,pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion> 4.0.0 </modelVersion>
<groupId> com.tp.neo4j </groupId>
<artifactId> springdata-neo4j </artifactId>
<version> 1.0 </version>
<dependencies>
<dependency>
<groupId> org.springframework.data </groupId>
<artifactId> spring-data-neo4j </artifactId>
<version> 3.1.2.RELEASE </version>
</dependency>
<dependency>
<groupId> org.neo4j </groupId>
<artifactId> neo4j-kernel </artifactId>
<version> 2.1.3 </version>
</dependency>
<dependency>
<groupId> javax.transaction </groupId>
<artifactId> jta </artifactId>
<version> 1.1 </version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
</dependencies>
</project>
最后
neo4j與java的結合有很多的方式,據目前我所知道的就有原生api
、driver方式
、springData neo4j
等三種方式。