为了能够使用Neo4j进行项目开发,今天看了相关的文档,利用Neo4j的Api在Java下面对其进行操作,故写下如此示例。
任务目标
添加User结点和Movie结点,并在这些结点中添加对应的关系,使它们之间可以关联起来,如下图所示:
图片来源和实例来源于
<blockquote>Vukotic A, Watt N, Abedrabbo T, et al. Neo4j in Action[C]// Manning Publications Co. 2014.</blockquote>
添加Dependency
使用内嵌的Neo4j数据库来进行操作,所以我们这儿需要对项目添加依赖,以便利我们可以在项目中引用Neo4j的Api来进行数据库操作。
<!-- https://mvnrepository.com/artifact/org.neo4j/neo4j -->
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>3.1.2</version>
</dependency>
取得Neo4j数据库
当对数据库进行操作的时候,我们需要先拿到数据库对象,因为我们使用的是购入的数据库,所以我们得指定数据文件的路径,如果该路径下面有数据库的话就用它进行操作,反之刚创建对应的数据库。开启事务,把所有的操作放到事务中进行处理,最后提交事务,关闭数据库。
GraphDatabaseService graphDb = new GraphDatabaseFactory()
.newEmbeddedDatabase(Dnew File("/tmp/graphDb"));
try (Transaction tx = graphDb.beginTx()) {
// 所有的数据库操作放到这里面执行。
tx.success();// 提交事务
}
graphDb.shutdown(); // 关闭数据库
定义Label
Neo4j之后的版本添加了 Label标签,来对数据进行会签分类。这儿的标签相当于生活中我们每个人身上的标签一样,如我属于学生而且我是一个男生,别人称我为学霸,从这名话中得出我身上打了三个标签,分别是学生、男生、学霸。同样的在Neo4j中,每个结点和每个关系都可以有0到多个标签。为了方便代码的书写,我们把所有的Label标签定义在一个枚举enum类中,但是我们的枚举类需要实现Label接口。Label 不仅便于我把把结点进行分类,同时在查询的时候利用 Label 进行查询,提高检索效率。
import org.neo4j.graphdb.Label;
public enum MyLabels implements Label {
MOVIES, USERS
}
定义Relationship
与定义Label相似,我们也需要把我们用到的Relationship定义在一个枚举类中,不同的是Relationship需要实现的接口是 RelationshipType 。
import org.neo4j.graphdb.RelationshipType;
public enum MyRelationshipTypes implements RelationshipType{
IS_FRIEND_OF,HAS_SEEN
}
添加Node
利用上面得到的 Neo4j 对象 GraphDatabaseService 创建我们需要的结点,同时指定结点对应的 Label 标签。
// Users
Node user1 = graphDb.createNode(MyLabels.USERS);
Node user2 = graphDb.createNode(MyLabels.USERS);
Node user3 = graphDb.createNode(MyLabels.USERS);
// Movies
Node movie1 = graphDb.createNode(MyLabels.MOVIES);
Node movie2 = graphDb.createNode(MyLabels.MOVIES);
Node movie3 = graphDb.createNode(MyLabels.MOVIES);
添加Properties
user1.setProperty("name", "John Johnson");
user2.setProperty("name", "Kate Smith");
user3.setProperty("name", "Jack Jeffries");
movie1.setProperty("name", "Fargo");
movie2.setProperty("name", "Alien");
movie3.setProperty("name", "Heat");
添加Relationship
user1.createRelationshipTo(user2, MyRelationshipTypes.IS_FRIEND_OF);
user1.createRelationshipTo(user3, MyRelationshipTypes.IS_FRIEND_OF);
添加 Relationship 并设置 Relationship 的属性
Relationship rel1 = user1.createRelationshipTo(movie1, MyRelationshipTypes.HAS_SEEN);
rel1.setProperty("stars", "5");
Relationship rel2 = user1.createRelationshipTo(movie3, MyRelationshipTypes.HAS_SEEN);
rel2.setProperty("stars", "3");
Relationship rel3 = user1.createRelationshipTo(movie1, MyRelationshipTypes.HAS_SEEN);
rel3.setProperty("stars", "4");
Relationship rel4 = user1.createRelationshipTo(movie2, MyRelationshipTypes.HAS_SEEN);
rel4.setProperty("stars", "5");
测试结果
当以上步骤完成之后,我们支行程序它就会向数据库中添加我们设置的结点和关系,下面验证上面的设置是否成功。
import java.io.File;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.ResourceIterable;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
public class AppTest {
public static void main(String[] args) {
File DB_File = new File("/tmp/graphDb");
GraphDatabaseService graphDb = new GraphDatabaseFactory()
.newEmbeddedDatabase(DB_File);
try (Transaction tx = graphDb.beginTx()) {
// Node
ResourceIterable<Node> nIt = graphDb.getAllNodes();
nIt.forEach((node) -> showNodes(node));
// commit transaction
tx.success();
}
// Stop the database
graphDb.shutdown();
}
private static void showNodes(Node node) {
System.out.print(node.getId() + "--");
node.getLabels().forEach((label) -> System.out.print(label + "--"));
node.getAllProperties().entrySet().forEach((entity) -> {
System.out.print(entity.getKey() + "--");
System.out.println(entity.getValue());
});
node.getRelationships().forEach((rel) -> System.out.println(rel));
}
}
结果
显示结果如所示,遍历出了我们设置的所有结点和所有关系,证明我们成功的利用Neo4j的Api对其进行了数据的写入和查询。
0--USERS--name--John Johnson
(0)-[HAS_SEEN,5]->(4)
(0)-[HAS_SEEN,4]->(3)
(0)-[HAS_SEEN,3]->(5)
(0)-[HAS_SEEN,2]->(3)
(0)-[IS_FRIEND_OF,1]->(2)
(0)-[IS_FRIEND_OF,0]->(1)
1--USERS--name--Kate Smith
(0)-[IS_FRIEND_OF,0]->(1)
2--USERS--name--Jack Jeffries
(0)-[IS_FRIEND_OF,1]->(2)
3--MOVIES--name--Fargo
(0)-[HAS_SEEN,4]->(3)
(0)-[HAS_SEEN,2]->(3)
4--MOVIES--name--Alien
(0)-[HAS_SEEN,5]->(4)
5--MOVIES--name--Heat
(0)-[HAS_SEEN,3]->(5)