Spring-Boot使用neo4j-java-driver-- 查找兩個節點之間關系的最短路徑


 

一、Cypher數據

 


   
   
  
  
          
  1. create (小北:朋友圈{姓名: "小北", 喜歡的書類: "Poetry"}),
  2. (小菲:朋友圈{姓名: "小菲", 喜歡的書類: "Science Fiction"}),
  3. (小鵬:朋友圈{姓名: "小鵬", 喜歡的書類: "Music"}),
  4. (小穎:朋友圈{姓名: "小穎", 喜歡的書類: "Politics"}),
  5. (小蘭:朋友圈{姓名: "小蘭", 喜歡的書類: "Music"}),
  6. (小峰:朋友圈{姓名: "小峰", 喜歡的書類: "Travel"}),
  7. (小訊:朋友圈{姓名: "小訊", 喜歡的書類: "Poetry"}),
  8. (小東:朋友圈{姓名: "小東", 喜歡的書類: "Sequential Art"}),
  9. (小唯:朋友圈{姓名: "小唯", 喜歡的書類: "Young Adult"}),
  10. (小竇:朋友圈{姓名: "小竇", 喜歡的書類: "Poetry"}),
  11. (小齊:朋友圈{姓名: "小齊", 喜歡的書類: "Default"}),
  12. (小林:朋友圈{姓名: "小林", 喜歡的書類: "Poetry"}),
  13. (小銳:朋友圈{姓名: "小銳", 喜歡的書類: "Default"}),
  14. (小偉:朋友圈{姓名: "小偉", 喜歡的書類: "Young Adult"}),
  15. (小玲:朋友圈{姓名: "小玲", 喜歡的書類: "Business"}),
  16. (小訊)-[:認識]->(小竇),
  17. (小訊)-[:認識]->(小齊),
  18. (小訊)-[:認識]->(小林),
  19. (小訊)-[:認識]->(小鵬),
  20. (小訊)-[:認識]->(小偉),
  21. (小訊)-[:認識]->(小峰),
  22. (小菲)-[:認識]->(小鵬),
  23. (小菲)-[:認識]->(小峰),
  24. (小菲)-[:認識]->(小唯),
  25. (小峰)-[:認識]->(小北),
  26. (小峰)-[:認識]->(小蘭),
  27. (小東)-[:認識]->(小林),
  28. (小東)-[:認識]->(小銳),
  29. (小東)-[:認識]->(小菲),
  30. (小鵬)-[:認識]->(小穎),
  31. (小北)-[:認識]->(小蘭),
  32. (小穎)-[:認識]->(小東),
  33. (小唯)-[:認識]->(小鵬),
  34. (小唯)-[:認識]->(小銳),
  35. (小偉)-[:認識]->(小玲)

 

 

 

二、執行后,neo4j browser中查詢效果如下

 

 

 

 

 

 

三、找出小訊和小銳之間的最短關系路徑

 

 

 

 

 

        如上圖,假設給你兩個人,一個人是節點小訊,另一個人是節點小銳,問他們之間的關系最短路徑是什么? 或者換句話問,小訊怎么用最少的步驟聯系到小銳?【前提是,小訊和小銳之間不存在任何關系,否則這種問題就沒有任何意義了,你倆都有關系了,我還問個毛啊,偷笑

 

       如果你用肉眼觀察的話,你會找到很多種小訊到達小銳的路徑,比如:

1、小訊認識小峰,小菲認識小峰(如果不考慮關系的反向,則認為小峰也同樣認識小菲),小菲又認識小唯,小唯認識小銳

因此這種路徑下小訊聯系小銳的步驟為: 小訊--小峰--小菲--小唯--小銳,路徑長度4

2、同上,我們還可以找出一條長度等於3的路徑:小訊--小林--小東--小銳

 

...... 等等,如果光靠肉眼觀察的話,像這種數據少的話,勉強還可以捋下來,但是數據一多,就歇菜了,我們可以用neo4j自帶的方法來算出兩個節點之間存在關系的前提下的最短到達路徑Path,比如:

 

查詢出所有小訊到小銳的關系最短路徑,語句如下:

 

MATCH n=allshortestPaths((a:朋友圈{姓名:"小訊"})-[*]-(b:朋友圈{姓名:"小銳"})) return n

 

查詢出的graph效果如下:

 

下圖標注的序號正是上面我們提到的長度等於3的一條路徑:小訊--小林--小東--小銳

 

 

 

如果我們只查出最短的一條路徑,我們使用shortestPath的時候只會查出一條結果,不管結果怎么樣,反正都是最短路徑!

 

語句如下:

 

MATCH n=shortestPath((a:朋友圈{姓名:"小訊"})-[*]-(b:朋友圈{姓名:"小銳"})) return n

 

 

 

 

四、找出小訊和小銳之間的深度等於4的路徑Path

 

 

MATCH (a:朋友圈{姓名:"小訊"}),(b:朋友圈{姓名:"小銳"})
return (a)-[*4]-(b) as p

 

 

 

 

 

 

如果你查找length(path) = 8的結果會怎么樣呢?

 

 

 

 

 

 

五、demo實現最短路徑信息輸出

 

 



Spring-Boot pom依賴

 

 

 


   
   
  
  
          
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. <modelVersion>4.0.0 </modelVersion>
  4. <groupId>com.appleyk </groupId>
  5. <artifactId>Spring-Boot-Neo4jAPI </artifactId>
  6. <version>0.0.1-SNAPSHOT </version>
  7. <packaging>war </packaging>
  8. <description>Spring-Boot 集成Neo4j,實現原生JavaAPI的節點、關系操作 </description>
  9. <parent>
  10. <groupId>org.springframework.boot </groupId>
  11. <artifactId>spring-boot-starter-parent </artifactId>
  12. <version>1.5.12.RELEASE </version>
  13. </parent>
  14. <properties>
  15. <java.version>1.8 </java.version>
  16. <janino.version>3.0.8 </janino.version>
  17. </properties>
  18. <dependencies>
  19. <dependency>
  20. <groupId>org.springframework.boot </groupId>
  21. <artifactId>spring-boot-starter-web </artifactId>
  22. </dependency>
  23. <!-- 添加熱部署 devtools:監聽文件變動 -->
  24. <!-- 當Java文件改動時,Spring-boo會快速重新啟動 -->
  25. <!-- 最簡單的測試,就是隨便找一個文件Ctrl+S一下,就可以看到效果 -->
  26. <dependency>
  27. <groupId>org.springframework.boot </groupId>
  28. <artifactId>spring-boot-devtools </artifactId>
  29. <!-- optional=true,依賴不會傳遞 -->
  30. <!-- 本項目依賴devtools;若依賴本項目的其他項目想要使用devtools,需要重新引入 -->
  31. <optional>true </optional>
  32. </dependency>
  33. <!-- Spring 單元測試 -->
  34. <dependency>
  35. <groupId>org.springframework.boot </groupId>
  36. <artifactId>spring-boot-starter-test </artifactId>
  37. <scope>test </scope>
  38. </dependency>
  39. <!-- JUnit單元測試 -->
  40. <dependency>
  41. <groupId>junit </groupId>
  42. <artifactId>junit </artifactId>
  43. </dependency>
  44. <!-- https://mvnrepository.com/artifact/org.neo4j.driver/neo4j-java-driver -->
  45. <dependency>
  46. <groupId>org.neo4j.driver </groupId>
  47. <artifactId>neo4j-java-driver </artifactId>
  48. <version>1.6.1 </version>
  49. </dependency>
  50. </dependencies>
  51. </project>

 

 

 

demo演示:

 


   
   
  
  
          
  1. import java.util.HashMap;
  2. import java.util.List;
  3. import java.util.Map;
  4. import org.junit.Test;
  5. import org.neo4j.driver.v1.AuthTokens;
  6. import org.neo4j.driver.v1.Driver;
  7. import org.neo4j.driver.v1.GraphDatabase;
  8. import org.neo4j.driver.v1.Record;
  9. import org.neo4j.driver.v1.Session;
  10. import org.neo4j.driver.v1.StatementResult;
  11. import org.neo4j.driver.v1.Value;
  12. import org.neo4j.driver.v1.types.Node;
  13. import org.neo4j.driver.v1.types.Path;
  14. import org.neo4j.driver.v1.types.Relationship;
  15. public class Neo4jBatchTest {
  16. Driver driver = GraphDatabase.driver( "bolt://localhost:7687", AuthTokens.basic( "neo4j", "n123"));
  17. private Session session = driver.session();
  18. /**
  19. * 批量創建
  20. *
  21. * @throws Exception
  22. */
  23. @ Test
  24. public void shortEstPath() throws Exception {
  25. try {
  26. String cmdSql = "MATCH n=shortestPath((a:朋友圈{姓名:'小訊'})-[*]-"
  27. + "(b:朋友圈{姓名:'小銳'})) return n";
  28. StatementResult result = session.run(cmdSql);
  29. while (result.hasNext()) {
  30. Record record = result.next();
  31. List< Value> values = record.values();
  32. Map< Long, Node> nodesMap = new HashMap<>();
  33. for ( Value value : values) {
  34. if (value.type().name().equals( "PATH")) {
  35. Path p = value.asPath();
  36. System.out. println( "小訊和小銳之間的關系最短路徑長度為:" + p.length());
  37. System.out. println( "====================================");
  38. Iterable< Node> nodes = p.nodes();
  39. for ( Node node : nodes) {
  40. nodesMap.put(node.id(), node);
  41. }
  42. /**
  43. * 打印最短路徑里面的關系 == 關系包括起始節點的ID和末尾節點的ID,以及關系的type類型
  44. */
  45. Iterable< Relationship> relationships = p.relationships();
  46. for ( Relationship relationship : relationships) {
  47. Long startID = relationship.startNodeId();
  48. Long endID = relationship.endNodeId();
  49. String rType = relationship.type();
  50. /**
  51. * asMap 相當於 節點的properties屬性信息
  52. */
  53. System.out. println(
  54. nodesMap. get(startID).asMap() + "-" + rType + "-"
  55. + nodesMap. get(endID).asMap());
  56. }
  57. }
  58. }
  59. }
  60. } catch ( Exception e) {
  61. System.err. println(e.getClass() + "," + e.getMessage());
  62. }
  63. }
  64. }

 

 

運行方法效果如下:

 

 

 

 

如果多條的話就:

 

String cmdSql = "MATCH n=allshortestPaths((a:朋友圈{姓名:'小訊'})-[*]-(b:朋友圈{姓名:'小銳'})) return n";
  
  
 
 
         

 

執行結果:

 

 

對比下,在neo4j中查詢的結果

 

 

原文地址:https://blog.csdn.net/Appleyk/article/details/80437746


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM