操作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 ) 来完成。

嵌入式模式

依赖

  1. <dependency>
  2. <groupId>org.neo4j</groupId>
  3. <artifactId>neo4j</artifactId>
  4. <version>3.5.11</version>
  5. </dependency>

获取Driver(连接)

GraphDatabaseService 是个非常重要的接口,所有的操作都是基于它。

  1. public static String DB_PATH="/opt/neo4j/neo4j-community-3.5.9/data/databases/online.db";
  2. public static GraphDatabaseService graphDb;
  3. public static GraphDatabaseService graphDB() {
  4. if (graphDb == null) {
  5. System.out.println("enter....");
  6. graphDb = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(
  7. new File(DB_PATH))
  8. .newGraphDatabase();
  9. registerShutdownHook(graphDb);
  10. }
  11. return graphDb;
  12. }
  13. /**
  14. * 程序退出时关闭neo4j
  15. * @param service
  16. */
  17. private static void registerShutdownHook(final GraphDatabaseService service) {
  18. Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
  19. @Override
  20. public void run() {
  21. service.shutdown();
  22. }
  23. }));
  24. }

获取所有Node

方法: getAllNodes()

  1. /**
  2. * 获取所有节点
  3. * @return
  4. */
  5. public static List<Node> getAllNodes() {
  6. return graphDB().getAllNodes().stream().collect(Collectors.toList());
  7. }

获取所有relations

方法: getAllRelationships()

  1. /**
  2. * 获取所有关系
  3. * @return
  4. */
  5. public static Map<String, Relationship> getAllRelations() {
  6. Map<String, Relationship> map = new HashMap<>();
  7. graphDB().getAllRelationships().forEach(r -> {
  8. Node sNode = r.getStartNode();
  9. Node endNode = r.getEndNode();
  10. long startId = sNode.getId();
  11. long endId = endNode.getId();
  12. long rId = r.getId();
  13. String composeId = startId+"_"+endId+"_"+rId;
  14. map.putIfAbsent(composeId, r);
  15. });
  16. return map;
  17. }

创建Node

  1. /**
  2. * 创建Node
  3. * @param properties
  4. * @param labels
  5. * @return
  6. */
  7. public static Node createNode(Map<String,Object> properties,String... labels) {
  8. Label[] lbs = new Label[labels.length];
  9. for (int i = 0; i < labels.length; i++) {
  10. lbs[i] = Label.label(labels[i]);
  11. }
  12. Node node = graphDB().createNode(lbs);
  13. properties.forEach((k,v) -> {
  14. node.setProperty(k,v);
  15. });
  16. return node;
  17. }

注意(重要)

上面几个方法使用的时候,都应该包含在事务块中。例如:

  1. try (Transaction tx = graphDB().beginTx()) {
  2. List<Node> nodes = getAllNodes();
  3. Map<String, Relationship> relations = getAllRelations();
  4. tx.success();
  5. }

服务器模式

依赖

  1. <!-- 只需引入这个jar -->
  2. <dependency>
  3. <groupId>org.neo4j.driver</groupId>
  4. <artifactId>neo4j-java-driver</artifactId>
  5. <version>1.7.5</version>
  6. </dependency>
  7. <!-- 第三方 -->
  8. <dependency>
  9. <groupId>org.yaml</groupId>
  10. <artifactId>snakeyaml</artifactId>
  11. <version>1.23</version>
  12. </dependency>

获取Driver

driver = GraphDatabase.driver( neo4j.getUri(), AuthTokens.basic( neo4j.getUsername(), neo4j.getPassword() ) );

  1. private final static Driver driver;
  2. static {
  3. Yaml yaml = new Yaml(new Constructor(Neo4j.class));
  4. InputStream stream = Neo4jUtils.class.getClassLoader().getResourceAsStream("neo4j.yml");
  5. Neo4j neo4j = yaml.load(stream);
  6. driver = GraphDatabase.driver( neo4j.getUri(), AuthTokens.basic( neo4j.getUsername(), neo4j.getPassword() ) );
  7. registerShutdownHook(driver);
  8. try {
  9. stream.close();
  10. } catch (IOException e) {
  11. e.printStackTrace();
  12. }
  13. }
  14. private static void registerShutdownHook(final Driver driver) {
  15. Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
  16. @Override
  17. public void run() {
  18. log.info("Close Neo4j Driver...");
  19. driver.close();
  20. }
  21. }));
  22. }

获取所有Node

关键是写Cypher语句: MATCH (n) RETURN n LIMIT {size}

  1. public static List<Node> findAllNode() {
  2. List<Node> nodes = new ArrayList<>();
  3. String cypher = "MATCH (n) RETURN n LIMIT {size}";
  4. try(Session session = driver.session()){
  5. StatementResult result = session.run(cypher, Values.parameters("size", 1000));
  6. result.stream().forEach(record -> {
  7. Node node = record.get("n").asNode();
  8. nodes.add(node);
  9. });
  10. }
  11. return nodes;
  12. }

获取所有Path

语句: MATCH p=() --> () RETURN p LIMIT {size}

  1. public static List<Path> findAllPaths() {
  2. List<Path> paths = new ArrayList<>();
  3. String cypher = "MATCH p=() --> () RETURN p LIMIT {size}";
  4. try(Session session = driver.session()){
  5. StatementResult result = session.run(cypher, Values.parameters("size", 1000));
  6. result.stream().forEach(record -> {
  7. Path path = record.get("p").asPath();
  8. paths.add(path);
  9. });
  10. }
  11. return paths;
  12. }
  13. /**
  14. * 解析关系数据
  15. * @param paths
  16. * @return
  17. */
  18. private List<Map<String, Object>> parseRelations(List<Path> paths) {
  19. List<Map<String, Object>> result = new ArrayList<>();
  20. for (Path path : paths) {
  21. //开始节点
  22. Node start = path.start();
  23. //尾节点
  24. Node end = path.end();
  25. path.relationships().forEach(r ->{
  26. Map<String, Object> relation = new LinkedHashMap<>();
  27. relation.putAll(r.asMap());
  28. });
  29. }
  30. return result;
  31. }

通过Id查找Node

语句: match (n) where id(n)=%d return n

  1. /**
  2. * 通过Id找Node
  3. * @param id
  4. * @return
  5. */
  6. public static Node findNodeById(Integer id) {
  7. String cypherOrigin = "match (n) where id(n)=%d return n";
  8. try(Session session = driver.session()){
  9. StatementResult result = session.run(String.format(cypherOrigin, id));
  10. return result.single().get("n").asNode();
  11. }
  12. }

通过Id修改Node

语句: match (n) where id(n) = 577 with n set n.Phones='15705625428' return n

  1. /**
  2. * 执行cypher语句
  3. * @param cypher
  4. */
  5. public static StatementResult exec(String cypher) {
  6. try(Session session = driver.session()){
  7. return session.run(cypher);
  8. }
  9. }
  10. String cypher="match (n) where id(n) = 577 with n set n.Phones='15705625428' return n";
  11. exec(cypher);