• 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
  • 相关阅读:
    【SSM电商项目后台开发】004-用户模块
    【SSM电商项目后台开发】003-项目架构概览
    C#面向对象编程「字段与属性」
    C#基本语法
    C#学习笔记-简介
    软件工程团队作业展示
    “消灭选择困难症”软件设计规格说明书
    “消灭选择困难APP”软件需求规格说明书
    消灭选择困难APP
    消灭选择困难
  • 原文地址:https://www.cnblogs.com/jpfss/p/11428190.html
Copyright © 2020-2023  润新知