操作neo4j有两种模式:嵌入式和服务器模式。最常用的是服务器模式。在服务器模式下,我们可以通过neo4j-driver的方式连接到server,使用run(cypher)方法执行cypher语句,从而获取查询结果。服务器模式的好处在于,在java代码中操作neo4j和用其他客户端操作neo4j是一样的。
但是嵌入式模式就不一样了,嵌入式模式启动的时候占用了 graph.db
文件。这时,除了这个java进程,其他人是访问不到这个neo4j的。但是它的优点也很明显,因为使用嵌入式模式实际使用的是neo4j的内核,所以能使用的api都是底层的。能做很多方便的事。比如根据id查找节点,嵌入式模式就有一个方法findById。如果要在服务器模式下实现这个功能,只能写cypher语句( match (n) where id(n) = 1 return n
) 来完成。
嵌入式模式
依赖
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>3.5.11</version>
</dependency>
获取Driver(连接)
GraphDatabaseService
是个非常重要的接口,所有的操作都是基于它。
public static String DB_PATH="/opt/neo4j/neo4j-community-3.5.9/data/databases/online.db";
public static GraphDatabaseService graphDb;
public static GraphDatabaseService graphDB() {
if (graphDb == null) {
System.out.println("enter....");
graphDb = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(
new File(DB_PATH))
.newGraphDatabase();
registerShutdownHook(graphDb);
}
return graphDb;
}
/**
* 程序退出时关闭neo4j
* @param service
*/
private static void registerShutdownHook(final GraphDatabaseService service) {
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
service.shutdown();
}
}));
}
获取所有Node
方法: getAllNodes()
/**
* 获取所有节点
* @return
*/
public static List<Node> getAllNodes() {
return graphDB().getAllNodes().stream().collect(Collectors.toList());
}
获取所有relations
方法: getAllRelationships()
/**
* 获取所有关系
* @return
*/
public static Map<String, Relationship> getAllRelations() {
Map<String, Relationship> map = new HashMap<>();
graphDB().getAllRelationships().forEach(r -> {
Node sNode = r.getStartNode();
Node endNode = r.getEndNode();
long startId = sNode.getId();
long endId = endNode.getId();
long rId = r.getId();
String composeId = startId+"_"+endId+"_"+rId;
map.putIfAbsent(composeId, r);
});
return map;
}
创建Node
/**
* 创建Node
* @param properties
* @param labels
* @return
*/
public static Node createNode(Map<String,Object> properties,String... labels) {
Label[] lbs = new Label[labels.length];
for (int i = 0; i < labels.length; i++) {
lbs[i] = Label.label(labels[i]);
}
Node node = graphDB().createNode(lbs);
properties.forEach((k,v) -> {
node.setProperty(k,v);
});
return node;
}
注意(重要)
上面几个方法使用的时候,都应该包含在事务块中。例如:
try (Transaction tx = graphDB().beginTx()) {
List<Node> nodes = getAllNodes();
Map<String, Relationship> relations = getAllRelations();
tx.success();
}
服务器模式
依赖
<!-- 只需引入这个jar -->
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
<version>1.7.5</version>
</dependency>
<!-- 第三方 -->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.23</version>
</dependency>
获取Driver
driver = GraphDatabase.driver( neo4j.getUri(), AuthTokens.basic( neo4j.getUsername(), neo4j.getPassword() ) );
private final static Driver driver;
static {
Yaml yaml = new Yaml(new Constructor(Neo4j.class));
InputStream stream = Neo4jUtils.class.getClassLoader().getResourceAsStream("neo4j.yml");
Neo4j neo4j = yaml.load(stream);
driver = GraphDatabase.driver( neo4j.getUri(), AuthTokens.basic( neo4j.getUsername(), neo4j.getPassword() ) );
registerShutdownHook(driver);
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void registerShutdownHook(final Driver driver) {
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
log.info("Close Neo4j Driver...");
driver.close();
}
}));
}
获取所有Node
关键是写Cypher语句: MATCH (n) RETURN n LIMIT {size}
public static List<Node> findAllNode() {
List<Node> nodes = new ArrayList<>();
String cypher = "MATCH (n) RETURN n LIMIT {size}";
try(Session session = driver.session()){
StatementResult result = session.run(cypher, Values.parameters("size", 1000));
result.stream().forEach(record -> {
Node node = record.get("n").asNode();
nodes.add(node);
});
}
return nodes;
}
获取所有Path
语句: MATCH p=() --> () RETURN p LIMIT {size}
public static List<Path> findAllPaths() {
List<Path> paths = new ArrayList<>();
String cypher = "MATCH p=() --> () RETURN p LIMIT {size}";
try(Session session = driver.session()){
StatementResult result = session.run(cypher, Values.parameters("size", 1000));
result.stream().forEach(record -> {
Path path = record.get("p").asPath();
paths.add(path);
});
}
return paths;
}
/**
* 解析关系数据
* @param paths
* @return
*/
private List<Map<String, Object>> parseRelations(List<Path> paths) {
List<Map<String, Object>> result = new ArrayList<>();
for (Path path : paths) {
//开始节点
Node start = path.start();
//尾节点
Node end = path.end();
path.relationships().forEach(r ->{
Map<String, Object> relation = new LinkedHashMap<>();
relation.putAll(r.asMap());
});
}
return result;
}
通过Id查找Node
语句: match (n) where id(n)=%d return n
/**
* 通过Id找Node
* @param id
* @return
*/
public static Node findNodeById(Integer id) {
String cypherOrigin = "match (n) where id(n)=%d return n";
try(Session session = driver.session()){
StatementResult result = session.run(String.format(cypherOrigin, id));
return result.single().get("n").asNode();
}
}
通过Id修改Node
语句: match (n) where id(n) = 577 with n set n.Phones='15705625428' return n
/**
* 执行cypher语句
* @param cypher
*/
public static StatementResult exec(String cypher) {
try(Session session = driver.session()){
return session.run(cypher);
}
}
String cypher="match (n) where id(n) = 577 with n set n.Phones='15705625428' return n";
exec(cypher);