Advertisement

知识图谱java实现_知识图谱:neo4j(四)Java API

阅读量:

知识图谱:neo4j(四)Java API

知识图谱:neo4j(四)Java API

Neo4j Java API

Neo4j 提供 JAVA API 以编程方式执行所有数据库操作。它支持两种类型的API:

1、Neo4j 原生的 Java API

2、Neo4j Cypher Java API

Neo4j 原生 Java API 是一种低级别的纯 JAVA API,用于执行数据库操作。Neo4j Cypher Java API 是简单而强大的 JAVA API,用于执行所有CQL命令以执行数据库操作。
664fb1b722ec3f9a69dfc9bec0a5cc42.png

环境配置

CentOS 6.9

Neo4j 3.5.3 [安装教程]

IDEA 2018.1 [安装教程]

Maven 3.1.1 [安装教程]

实验

1. 创建SpringBoot项目

因为Neo4j依赖的jar包比较多,所以推荐使用Maven来管理。
4174a7810ddc26a7437d2fb252c59bcb.png
9c7d0da5ed4ac5dd7fb9a2b2fde93347.png

这步不操作也行,该案例中用不到...
a886b145fa5ac5df2535f2870f31eeba.png

在 pom.xml 中添加依赖

org.neo4j

neo4j

3.5.3

2. 新建一个Java类 Neo4jNativeJavaAPI
b173042f86adf8dd79bfb89dc7ad5ba6.png

3. 导入需要的库包

import java.io.File;

import org.neo4j.graphdb.Direction;

import org.neo4j.graphdb.GraphDatabaseService;

import org.neo4j.graphdb.Label;

import org.neo4j.graphdb.Node;

import org.neo4j.graphdb.Relationship;

import org.neo4j.graphdb.RelationshipType;

import org.neo4j.graphdb.Transaction;

import org.neo4j.graphdb.factory.GraphDatabaseFactory;

或者

import java.io.File;

import org.neo4j.graphdb.*;

import org.neo4j.graphdb.factory.GraphDatabaseFactory;

4. 无论是创建一个新的数据库,还是打开一个已有的数据库,首先都需要创建一个GraphDatabaseService实例

// GraphDatabaseService实例可以被多个线程共享,但是一个数据库只允许有一个Service实例

GraphDatabaseService graphDB = new GraphDatabaseFactory().newEmbeddedDatabase( DB_PATH );

可以对数据库进行一些配置(更多配置信息可以看GraphDatabaseSettings类的文档

GraphDatabaseService graphDB = new GraphDatabaseFactory()

.newEmbeddedDatabaseBuilder( testDirectory.graphDbDir() )

.setConfig( GraphDatabaseSettings.pagecache_memory, "512M" )

.setConfig( GraphDatabaseSettings.string_block_size, "60" )

.setConfig( GraphDatabaseSettings.array_block_size, "300" )

.newGraphDatabase();

为了确保数据库正确地关闭,可添加一个ShutdownHook来实现关闭数据库的动作。关闭数据库可以调用shutdown()方法

private static void registerShutdownHook(final GraphDatabaseService graphDb) {

Runtime.getRuntime().addShutdownHook(new Thread() {

@Override

public void run() {

graphDb.shutdown();

}

});

}

5. 创建节点和关系

关系、Label类型可以通过枚举enum创建

// Label类型枚举类

private static enum MyLabels implements Label {

MOVIES, USERS

}

//关系类型枚举类

private static enum MyRelationshipTypes implements RelationshipType {

IS_FRIEND_OF, HAS_SEEN

}

6. 在Neo4j中,对于数据库的操作需要在一个事务transaction中执行

try ( Transaction tx = graphDb.beginTx() ){

// 数据库操作写在事务提交之前

tx.success();

}

7. 汇总上述并给出一个案例

import org.neo4j.graphdb.*;

import org.neo4j.graphdb.factory.GraphDatabaseFactory;

import java.io.File;

public class Neo4jNativeJavaAPI {

private static void registerShutdownHook(final GraphDatabaseService graphDB) {

Runtime.getRuntime().addShutdownHook(

new Thread() {

public void run() {

System.out.println("Server is shutting down");

graphDB.shutdown();

}

}

);

}

//Label类型枚举类

private static enum MyLabels implements Label {

MOVIES, USERS

}

//关系类型枚举类

private static enum MyRelationshipTypes implements RelationshipType {

IS_FRIEND_OF, HAS_SEEN

}

public static void main(String[] args) {

//指定 Neo4j 存储路径

File file = new File("/usr/local/neo4j/data/databases/test.db");

//Create a new Object of Graph Database

GraphDatabaseService graphDB = new GraphDatabaseFactory().newEmbeddedDatabase(file);

System.out.println("Server is up and Running");

try(Transaction tx = graphDB.beginTx()){

//新增Actor节点 添加Label以区分节点类型 每个节点设置name属性

Node actor1 = graphDB.createNode(MyLabels.ACTORS);

actor1.setProperty("name", "John Johnson");

Node actor2 = graphDB.createNode(MyLabels.ACTORS);

actor2.setProperty("name", "Kate Smith");

Node actor3 = graphDB.createNode(MyLabels.ACTORS);

actor3.setProperty("name", "Jack Jeffries");

/**

  • 为user1添加Friend关系

  • 注:Neo4j的关系是有向的箭头,正常来讲Friend关系应该是双向的,

  • 此处为了简单起见,将关系定义成单向的,不会影响后期的查询

*/

actor1.createRelationshipTo(user2,MyRelationshipTypes.IS_FRIEND_OF);

actor1.createRelationshipTo(user3,MyRelationshipTypes.IS_FRIEND_OF);

/**

  • 新增Movie节点

  • 添加Lable以区分节点类型

  • 每个节点设置name属性

*/

Node movie1 = graphDB.createNode(MyLabels.MOVIES);

movie1.setProperty("name", "Fargo");

Node movie2 = graphDB.createNode(MyLabels.MOVIES);

movie2.setProperty("name", "Alien");

Node movie3 = graphDB.createNode(MyLabels.MOVIES);

movie3.setProperty("name", "Heat");

/**

  • 为User节点和Movie节点之间添加HAS_SEEN关系, HAS_SEEN关系设置stars属性

*/

Relationship relationship1 = user1.createRelationshipTo(movie1, MyRelationshipTypes.HAS_SEEN);

relationship1.setProperty("stars", 5);

Relationship relationship2 = user2.createRelationshipTo(movie3, MyRelationshipTypes.HAS_SEEN);

relationship2.setProperty("stars", 3);

Relationship relationship6 = user2.createRelationshipTo(movie2, MyRelationshipTypes.HAS_SEEN);

relationship6.setProperty("stars", 6);

Relationship relationship3 = user3.createRelationshipTo(movie1, MyRelationshipTypes.HAS_SEEN);

relationship3.setProperty("stars", 4);

Relationship relationship4 = user3.createRelationshipTo(movie2, MyRelationshipTypes.HAS_SEEN);

relationship4.setProperty("stars", 5);

tx.success();

System.out.println("Done successfully");

} catch (Exception e) {

e.printStackTrace();

} finally {

graphDB.shutdown(); //关闭数据库

}

//Register a Shutdown Hook

registerShutdownHook(graphDB);

}

}

运行后却报错了:Error starting org.neo4j.graphdb.facade.GraphDatabaseFacadeFactory
958bc8c498f80832ff04597c7e6102e2.png

在网上没有找到明确的解决办法,但找到类似的 [链接],说是因为已经成功初始化,但是在继续初始化启动就会报错,那很简单的解决方法就是把neo4j安装目录下的/data/databases里面的所有文件都删除掉(可以先备份再删掉),操作后再运行程序成功了
4711f231274b7a9ddbe28cba1f0cacc7.png

由于neo4j默认启动的是graph.db数据库,而我们这里用了新的数据库test.db,所以到/conf/neo4j.conf修改配置
95167c9463e15a7d4a5bcd6d7a18e421.png

启动neo4j
5a157fe4d8f27a7e0256217480b1c2d2.png

浏览器打开http://localhost:7474
98eece66d1f1967246b1c0481cb97a58.png

8. 再创建一个Java类Neo4jCypherJavaAPI,用 Cypher 对上图进行查询

import org.neo4j.graphdb.*;

import org.neo4j.graphdb.factory.GraphDatabaseFactory;

import java.io.File;

public class Neo4jCypherJavaAPI {

public static void main(String[] args) {

//指定 Neo4j 存储路径

File file = new File("/usr/local/neo4j/data/databases/test.db");

//Create a new Object of Graph Database

GraphDatabaseService graphDB = new GraphDatabaseFactory().newEmbeddedDatabase(file);

System.out.println("Server is up and Running");

try(Transaction tx = graphDB.beginTx()){

//通过Cypher查询获得结果

StringBuilder sb = new StringBuilder();

sb.append("MATCH (john)-[:IS_FRIEND_OF]->(USER)-[:HAS_SEEN]->(movie) ");

sb.append("RETURN movie");

Result result = graphDB.execute(sb.toString());

//遍历结果

while(result.hasNext()){

//get("movie")和查询语句的return movie相匹配

Node movie = (Node) result.next().get("movie");

System.out.println(movie.getId() + " : " + movie.getProperty("name"));

}

tx.success();

System.out.println("Done successfully");

} catch (Exception e) {

e.printStackTrace();

} finally {

graphDB.shutdown(); //关闭数据库

}

}

}
58084c7dd88c967ad6b5e4780a298d59.png

更多

1. 上述代码主要实现的是创建(CREATE)节点和关系,也可以进行更新、查询、删除等

try (Transaction tx = graphDB.beginTx()) {

// 查询节点

Node node = graphDB.findNode(MyLabels.ACTORS, "name", "John Johnson");

System.out.println("query node name is " + node.getProperty("name"));

// 更新节点

node.setProperty("birthday", "1979-01-18");

System.out.println(node.getProperty("name") + "'s birthday is " +

node.getProperty("birthday", new String()));

// 删除关系和节点

Relationship relationship = node.getSingleRelationship(MyRelationshipTypes.IS_FRIEND_OF, Direction.OUTGOING);

relationship.delete();

relationship.getStartNode().delete();

node.delete();

// 提交事务

tx.success();

}

2. Neo4j可以以两种方式运行 [链接]:

2.1 Java应用程序中的嵌入式数据库(如:本篇博文用的该方式

嵌入式Neo4j数据库是性能的最佳选择。 它运行在相同的客户端应用程序的进程托管它并将数据存储在给定的路径中。

2.2 通过REST的独立服务器(如:基于电影知识图谱的智能问答系统 用的该方式

作为独立应用程序,它比嵌入式配置更安全(客户端中的潜在故障不会影响服务器),并且更易于监控。要连接到Neo4j服务器,必须使用REST API,可以使用Python,.NET,Java,Go,PHP,Ruby,Node.js等。使用服务器开发的方式,Neo4j必须是开启的状态

参考

修行修心:图数据库 Neo4j 之 Java Api 的使用

博客园 没课割绿地:Neo4j学习笔记(1)——使用Java API实现简单的增删改查

Karenmaxx:Springboot连接Neo4j 完整版(提供代码)

知识图谱:neo4j(四)Java API相关教程

全部评论 (0)

还没有任何评论哟~