1. 程式人生 > >Neo4j的使用與Java呼叫例項

Neo4j的使用與Java呼叫例項

一. Neo4j簡介:

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

在一個圖中包含兩種基本的資料型別:Nodes(節點) 和 Relationships(關係)。Nodes 和 Relationships 包含key/value形式的屬性。Nodes通過Relationships所定義的關係相連起來,形成關係型網路結構。

相比其他NoSQL資料庫,Neo4j的特點在於可以建立關係,達到資料關聯的目的。從某些方面來說,我覺得它甚至可以取代關係型資料庫,而且不需要事先定義表結構,欄位擴充套件非常方便。

它使用的查詢語言是Cypher。

二. Neo4j的核心概念:

1. Nodes(節點)

節點包含多個標籤和屬性,就像是一個地鐵站。

一個節點就是一條資料。

2. Relations(關係)

關係是用來連線兩個節點的,也可以包含多個標籤和屬性,就像是地鐵站之間的線路。

一個關係也是一條資料。

關係包括進和出兩種方向。

3. Properties(屬性)

類似於關係型資料庫裡面的欄位,不用事先定義,可以動態新增。

4. Labels(標籤)

表示節點或者關係的型別,可以有多個,使查詢更加方便和高效。

三. Neo4j的配置和使用:

下載最新的Neo4j:http://neo4j.com/download/

解壓後移動到Neo4j下的bin目錄,啟動命令:neo4j.bat console


預設埠:7474

可在conf/neo4j.conf裡面修改配置

在瀏覽器輸入localhost:7474,登入Neo4j進行操作,預設使用者名稱/密碼:neo4j/neo4j,登陸後需要立刻修改密碼。


①:Cypher查詢語句

②:各種Labels及其數量

③:節點和關係的圖形介面

④:某節點包含的屬性

四. Cypher的基本語法:

1. 建立節點:

CREATE (n:Label {name:"L1", type:"T1"})
可以理解成:INSERT INTO Label(name, type) VALUES("L1", "T1")

n是變數名,可以任意。Label是標籤,可以有多個。{}裡面是屬性,可以有多個。

這個建立節點的例子中,包含了2個標籤:

CREATE (n:Label:Test {name:"L1", type:"T1"})

2. 查詢節點:

MATCH(a:Test) WHERE a.name="L1" RETURN a;

3. 建立多個節點和關係:

CREATE (節點1),(節點2),(節點3),(節點1)-[關係1]->(節點2),(節點2)-[關係2]->(節點3)

例:CREATE (a:Node), (b:Node), (a)-[:Relate]->(b)

如果已有Node,只想新增關聯,可用下面這種方法:

MATCH(a:Node),(b:Node) WHERE ID(a)=230 AND ID(b)=231 CREATE (b)-[:R]->(a)

4. 模式匹配:

根據關聯進行資料查詢。

MATCH (a)-[:Have]-(b)-[:Have]-(c)-[:Have]-(d) WHERE a.name="G1" RETURN a,b,c,d

5. 更新節點:

MATCH(n:Label) WHERE n.name="N2" SET n.update = "2018-06-26" 

6. 刪除節點:

MATCH(n) WHERE ID(n)=100 DELETE n

7. 檢視語句分析:

在查詢語句前加上

EXPLAIN

PROFILE

五. Java實現的介面和例項:

我用的是SpringBoot的專案,可以直接啟動ConsumerClientApplication,不用放到Tomcat下。

1. pom.xml中引入neo4j的jar包:

	    <dependency>
	    <!-- 伺服器開發需要的jar包 -->
	      <groupId>org.neo4j.driver</groupId>
	      <artifactId>neo4j-java-driver</artifactId>
	      <version>1.5.0</version>
	    </dependency>
	    <dependency>
	    <!-- 嵌入式開發需要的jar包 -->
	        <groupId>org.neo4j</groupId>
	        <artifactId>neo4j</artifactId>
	        <version>3.3.4</version>
	    </dependency>

2. 建立Code物件,用來傳遞引數:

package com.inesa.neo4j.entity;

public class Code {

	private String id;
	private String node;
	private String relation;
	private String property;
	private String label;

	private String nodeFromId;
	private String nodeFromLabel;
	private String nodeToId;
	private String nodeToLabel;
	
	private String where;
	private String update;
	private String result;
	
	public String getNode() {
		return node;
	}
	public void setNode(String node) {
		this.node = node;
	}
	public String getRelation() {
		return relation;
	}
	public void setRelation(String relation) {
		this.relation = relation;
	}
	public String getProperty() {
		return property;
	}
	public void setProperty(String property) {
		this.property = property;
	}
	public String getLabel() {
		return label;
	}
	public void setLabel(String label) {
		this.label = label;
	}
	public String getNodeFromId() {
		return nodeFromId;
	}
	public void setNodeFromId(String nodeFromId) {
		this.nodeFromId = nodeFromId;
	}
	public String getNodeToId() {
		return nodeToId;
	}
	public void setNodeToId(String nodeToId) {
		this.nodeToId = nodeToId;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getNodeFromLabel() {
		return nodeFromLabel;
	}
	public void setNodeFromLabel(String nodeFromLabel) {
		this.nodeFromLabel = nodeFromLabel;
	}
	public String getNodeToLabel() {
		return nodeToLabel;
	}
	public void setNodeToLabel(String nodeToLabel) {
		this.nodeToLabel = nodeToLabel;
	}
	public String getWhere() {
		return where;
	}
	public void setWhere(String where) {
		this.where = where;
	}
	public String getUpdate() {
		return update;
	}
	public void setUpdate(String update) {
		this.update = update;
	}
	public String getResult() {
		return result;
	}
	public void setResult(String result) {
		this.result = result;
	}

}

3. 建立Controller,新增介面:

package com.inesa.neo4j.controller;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.neo4j.driver.v1.AuthTokens;
import org.neo4j.driver.v1.Driver;
import org.neo4j.driver.v1.GraphDatabase;
import org.neo4j.driver.v1.Record;
import org.neo4j.driver.v1.Session;
import org.neo4j.driver.v1.StatementResult;
import static org.neo4j.driver.v1.Values.parameters;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.inesa.common.entity.RestfulResult;
import com.inesa.common.utils.CommUtils;
import com.inesa.common.utils.Constants;
import com.inesa.neo4j.entity.Code;

/**
 * Controller
 * 
 * @author sun
 * @version 2018-06-01
 */
@RestController
@RequestMapping(value = "neo4j")
public class CodeController {
    
    private Driver createDrive(){
		return GraphDatabase.driver( "bolt://localhost:7687", AuthTokens.basic( "neo4j", "admin" ) );
    }
    
    @RequestMapping(value = "test")
	public void test(HttpServletRequest request, HttpServletResponse response) {
		RestfulResult restfulResult = new RestfulResult();
		
		try{			
			Driver driver = createDrive();
	        Session session = driver.session();
	        
	        session.run( "CREATE (a:Person {name: {name}, title: {title}})",
	                parameters( "name", "Arthur001", "title", "King001" ) );

	        StatementResult result = session.run( "MATCH (a:Person) WHERE a.name = {name} " +
	                                              "RETURN a.name AS name, a.title AS title",
	                parameters( "name", "Arthur001" ) );
	        
	        while ( result.hasNext() )
	        {
	            Record record = result.next();
	            System.out.println( record.get( "title" ).asString() + " " + record.get( "name" ).asString() + " " + record.get( "id" ).asString() );
	        }
	        
	        session.close();
	        driver.close();
			
		}catch(Exception e){
			restfulResult.setResult(Constants.RESULT_STATE_ERROR);
			restfulResult.setMessage(e.getMessage());
		}
		
    	CommUtils.printDataJason(response, restfulResult);
	}

	@RequestMapping(value = "save")
	public void save(HttpServletRequest request, HttpServletResponse response,
			@RequestBody Code code) {
    	
		RestfulResult restfulResult = new RestfulResult();
		
		try{	
			Driver driver = createDrive();
	        Session session = driver.session();
	        
	        StatementResult result =  session.run( "CREATE (a:" + code.getLabel() + " {" + code.getProperty() + "}) return a");
	        
	        while (result.hasNext())
	        {
	            Record record = result.next();
		        restfulResult.setData(record.fields().get(0).value().toString().replace("node<", "").replace(">", ""));
	        }
	        
	        session.close();
	        driver.close();
			
		}catch(Exception e){
			restfulResult.setResult(Constants.RESULT_STATE_ERROR);
			restfulResult.setMessage(e.getMessage());
		}
		
    	CommUtils.printDataJason(response, restfulResult);
	}

	@RequestMapping(value = "update")
	public void update(HttpServletRequest request, HttpServletResponse response,
			@RequestBody Code code) {
    	
		RestfulResult restfulResult = new RestfulResult();
		
		try{	
			Driver driver = createDrive();
	        Session session = driver.session();
	        
	        StatementResult result = session.run("MATCH (a:" + code.getLabel() + ") WHERE a." + code.getWhere() + " SET a." + code.getUpdate() + " return COUNT(a)");
	        
	        while (result.hasNext())
	        {
	            Record record = result.next();
		        restfulResult.setData(record.fields().get(0).value().toString());
	        }
	        
	        session.close();
	        driver.close();
			
		}catch(Exception e){
			restfulResult.setResult(Constants.RESULT_STATE_ERROR);
			restfulResult.setMessage(e.getMessage());
		}
		
    	CommUtils.printDataJason(response, restfulResult);
	}

    @RequestMapping(value = "delete")
	public void delete(HttpServletRequest request, HttpServletResponse response,
			@RequestBody Code code) {
		RestfulResult restfulResult = new RestfulResult();
		
		try{			
			Driver driver = createDrive();
	        Session session = driver.session();
	        session.run( "match (n) where ID(n) = " + code.getId() +" detach delete n");
	        
	        session.close();
	        driver.close();
			
		}catch(Exception e){
			restfulResult.setResult(Constants.RESULT_STATE_ERROR);
			restfulResult.setMessage(e.getMessage());
		}
		
    	CommUtils.printDataJason(response, restfulResult);
	}

    @RequestMapping(value = "search")
	public void search(HttpServletRequest request, HttpServletResponse response,
			@RequestBody Code code) {
		RestfulResult restfulResult = new RestfulResult();
		
		try{			
			Driver driver = createDrive();
	        Session session = driver.session();

	        StatementResult result = session.run("MATCH " + code.getProperty() +
	        									" MATCH " + code.getRelation() +
	        									" WHERE " + code.getWhere() +
	                                              " RETURN " + code.getResult());
	        List<String> resultList = new ArrayList<String>();
	        while ( result.hasNext() )
	        {
	            Record record = result.next();
	            resultList.add(record.get("id").toString() + " " + record.get("name").toString());
	        }
	        
	        session.close();
	        driver.close();
	        
	        restfulResult.setData(resultList);
			
		}catch(Exception e){
			restfulResult.setResult(Constants.RESULT_STATE_ERROR);
			restfulResult.setMessage(e.getMessage());
		}
		
    	CommUtils.printDataJason(response, restfulResult);
	}

    @RequestMapping(value = "relate")
	public void relate(HttpServletRequest request, HttpServletResponse response,
			@RequestBody Code code) {
		RestfulResult restfulResult = new RestfulResult();
		
		try{
			Driver driver = createDrive();
	        Session session = driver.session();
	        
	        session.run("MATCH (a:" + code.getNodeFromLabel() + "), (b:" + code.getNodeToLabel() + ") " +
	        		"WHERE ID(a) = " + code.getNodeFromId() + " AND ID(b) = " + code.getNodeToId()
	        		+ " CREATE (a)-[:" + code.getRelation() + "]->(b)");
	        
	        session.close();
	        driver.close();
			
		}catch(Exception e){
			restfulResult.setResult(Constants.RESULT_STATE_ERROR);
			restfulResult.setMessage(e.getMessage());
		}
		
    	CommUtils.printDataJason(response, restfulResult);
	}

	//private static final String DB_PATH = "D:/neo4j/data/databases/graph.db";
	
	//GraphDatabaseService graphDb;
	
	/*@RequestMapping(value = "save")
	public void save(HttpServletRequest request, HttpServletResponse response,
			@RequestBody Code code) {
    	
		RestfulResult restfulResult = new RestfulResult();
		
		try{		
			if (graphDb == null)
				this.graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(new File(DB_PATH));
			
			registerShutdownHook(graphDb);
			
			Transaction tx = graphDb.beginTx();
		
			Node node = this.graphDb.createNode();
			Label label = DynamicLabel.label(code.getLabel());
			node.addLabel(label);
			node.setProperty("Name", code.getProperty());

            tx.success();
            
            restfulResult.setData(node.getId());
			
		}catch(Exception e){
			restfulResult.setResult(Constants.RESULT_STATE_ERROR);
			restfulResult.setMessage(e.getMessage());
		}
		
    	CommUtils.printDataJason(response, restfulResult);
	}*/
    
/*    private void registerShutdownHook(final GraphDatabaseService graphDB){
        //關閉暫存器
        Runtime.getRuntime().addShutdownHook(new Thread(){
            public void run(){
                graphDB.shutdown();
            }
        });
    }*/
}

我這裡只是做了幾個簡單的Sample,呼叫方式如下:

(1) 建立節點(save)


(2) 刪除節點(delete)


(3) 修改節點(update)


(4) 新增節點關係(relate)


(5) 自定義條件查詢(search)


結果資料:


GitHub地址:https://github.com/sunroyi/neo4j.git