Neo4j基本入門


Neo4j基本入門

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

一、基本概念

neo4j存儲節點
neo4j存儲節點

1. 標簽(Label)

Neo4j中,一個節點可以有一個以上的標簽,從現實世界的角度去看,一個標簽可以認為節點的某個類別,比如BOOKMOVIE等等。

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

查找結果:

返回排序后前3條結果
返回排序后前3條結果

4. 刪除節點delete命令

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

刪除一個不存在Relationship節點,會報錯:

刪除一個存在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屬性后的節點:

刪除birthday屬性后的節點
刪除birthday屬性后的節點

6. neo4j的字符串函數

upper,lower,substring,replac四種字符串的操作,其中upperlower在將來的版本中會被修改為toupper/tolower

大寫轉換操作結果:

大小寫轉換
大小寫轉換

7. 聚合函數AGGREGATION

常用的聚合函數有COUNTMAXMINAVGSUM等五種。

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的設計思路及基本概念:

  1. Label接口,表示標簽,實現這個接口的類,就可以當標簽使用;
  2. Relationship接口,別是關系,實現這個接口的類,就可以表示關系;
  3. 通過GraphDatabaseFactory這個類的實例化對象可以獲取GraphDatabaseService實例;
  4. GraphDatabaseService實例對象,可以獲取一個操作事務,通過這個事務可以實現任何操作異常的回滾,操作成功需要調用tx.success()方法;
  5. GraphDatabaseService 對象可以創建節點node;
  6. 節點node可以設置屬性setProperty(key,value);
  7. 節點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 的操作

操作思路:

  1. 創建一個與圖數據庫存儲數據對應的實體類entity,並進行必要的注解;
  2. dao層接口繼承Spring data Neo4jGraphRepositoryGraphTemplateCrudRepositoryPaginationAndSortingRepository,這個和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的結合有很多的方式,據目前我所知道的就有原生apidriver方式springData neo4j等三種方式。


免責聲明!

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



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