玩 GraphX 的时候知道了 GraphFrames ,玩 GraphFrames 的时候知道了 Cypher ,于是入坑 Neo4j。
https://neo4j.com/download/other-releases/,从上述链接选择合适的版本下载即可。
Neo4j-环境设置
Neo4j - Zip环境设置
上述链接仅供参考。由于不同版本之间存在差异,细节上会有些许不同。(the devil is in the details.)
笔者的安装环境:
Windows7 64
jdk-8u144-windows-x64.exe
neo4j-community-3.2.6-windows.zip
可以参考 这里 搭建开发环境。当然,也可以在 IDEA 的 maven 工程中添加如下依赖,就这么简单。
org.neo4j
neo4j
3.2.6
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命令以执行数据库操作。
import org.neo4j.graphdb.*;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import java.io.File;
public class Neo4jNativeJavaAPI {
private static void registerShutdownHook(final GraphDatabaseService graphDB) {
// Registers a shutdown hook for the Neo4j instance so that it shuts down nicely
// when the VM exits (even if you "Ctrl-C" the running example before it's completed)
/*为了确保neo4j数据库的正确关闭,我们可以添加一个关闭钩子方法 registerShutdownHook。
*这个方法的意思就是在jvm中增加一个关闭的钩子,
*当jvm关闭的时候,会执行系统中已经设置的所有通过方法addShutdownHook添加的钩子,
*当系统执行完这些钩子后,jvm才会关闭。
*所以这些钩子可以在jvm关闭的时候进行内存清理、对象销毁等操作。*/
Runtime.getRuntime().addShutdownHook(
new Thread() {
public void run() {
//Shutdown the Database
System.out.println("Server is shutting down");
graphDB.shutdown();
}
}
);
}
public static void main(String[] args) {
//指定 Neo4j 存储路径
File file = new File("D:\\neo4j-community-3.2.6\\data\\databases\\graph.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()){
/**
* 新增User节点
* 添加Lable以区分节点类型
* 每个节点设置name属性
*/
Node user1 = graphDB.createNode(MyLabels.USERS);
user1.setProperty("name", "John Johnson");
Node user2 = graphDB.createNode(MyLabels.USERS);
user2.setProperty("name", "Kate Smith");
Node user3 = graphDB.createNode(MyLabels.USERS);
user3.setProperty("name", "Jack Jeffries");
/**
* 为user1添加Friend关系
* 注:Neo4j的关系是有向的箭头,正常来讲Friend关系应该是双向的,
* 此处为了简单起见,将关系定义成单向的,不会影响后期的查询
*/
user1.createRelationshipTo(user2,MyRelationshipTypes.IS_FRIEND_OF);
user1.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);
}
}
/**
* Label类型枚举类
*/
enum MyLabels implements Label {
MOVIES, USERS
}
/**
* 关系类型枚举类
*/
enum MyRelationshipTypes implements RelationshipType {
IS_FRIEND_OF, HAS_SEEN
}
运行完毕后,在 neo4j-community-3.2.6 目录下执行
./bin/neo4j.bat console
输出如下
2017-11-01 03:24:32.585+0000 INFO ======== Neo4j 3.2.6 ========
2017-11-01 03:24:32.601+0000 INFO Starting...
2017-11-01 03:24:33.552+0000 INFO Bolt enabled on 127.0.0.1:7687.
2017-11-01 03:24:36.714+0000 INFO Started.
2017-11-01 03:24:37.571+0000 INFO Remote interface available at http://localhost:7474/
此时,在 http://localhost:7474/ 能够看到如下图
在 Java 程序中用 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("D:\\neo4j-community-3.2.6\\data\\databases\\graph.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(); //关闭数据库
}
}
}
输出如下:
Server is up and Running
8 : Alien
9 : Heat
8 : Alien
7 : Fargo
Done successfully