操作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() {@Overridepublic 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() {@Overridepublic 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);
