Neo4j的使用与Java调用实例

    技术2022-07-16  70

    版权 一. 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  

    Processed: 0.016, SQL: 9