Spring-Boot使用neo4j-java-driver-- 查找两个节点之间关系的最短路径

 

一、Cypher数据

 

create (小北:朋友圈{姓名:"小北", 喜欢的书类:"Poetry"}),
(小菲:朋友圈{姓名:"小菲", 喜欢的书类:"Science Fiction"}),
(小鹏:朋友圈{姓名:"小鹏", 喜欢的书类:"Music"}),
(小颖:朋友圈{姓名:"小颖", 喜欢的书类:"Politics"}),
(小兰:朋友圈{姓名:"小兰", 喜欢的书类:"Music"}),
(小峰:朋友圈{姓名:"小峰", 喜欢的书类:"Travel"}),
(小讯:朋友圈{姓名:"小讯", 喜欢的书类:"Poetry"}),
(小东:朋友圈{姓名:"小东", 喜欢的书类:"Sequential Art"}),
(小唯:朋友圈{姓名:"小唯", 喜欢的书类:"Young Adult"}),
(小窦:朋友圈{姓名:"小窦", 喜欢的书类:"Poetry"}),
(小齐:朋友圈{姓名:"小齐", 喜欢的书类:"Default"}),
(小林:朋友圈{姓名:"小林", 喜欢的书类:"Poetry"}),
(小锐:朋友圈{姓名:"小锐", 喜欢的书类:"Default"}),
(小伟:朋友圈{姓名:"小伟", 喜欢的书类:"Young Adult"}),
(小玲:朋友圈{姓名:"小玲", 喜欢的书类:"Business"}),
(小讯)-[:认识]->(小窦),
(小讯)-[:认识]->(小齐),
(小讯)-[:认识]->(小林),
(小讯)-[:认识]->(小鹏),
(小讯)-[:认识]->(小伟),
(小讯)-[:认识]->(小峰),
(小菲)-[:认识]->(小鹏),
(小菲)-[:认识]->(小峰),
(小菲)-[:认识]->(小唯),
(小峰)-[:认识]->(小北),
(小峰)-[:认识]->(小兰),
(小东)-[:认识]->(小林),
(小东)-[:认识]->(小锐),
(小东)-[:认识]->(小菲),
(小鹏)-[:认识]->(小颖),
(小北)-[:认识]->(小兰),
(小颖)-[:认识]->(小东),
(小唯)-[:认识]->(小鹏),
(小唯)-[:认识]->(小锐),
(小伟)-[:认识]->(小玲)

 

 

 

二、执行后,neo4j browser中查询效果如下

 

 

Spring-Boot使用neo4j-java-driver-- 查找两个节点之间关系的最短路径_第1张图片

 

 

 

 

三、找出小讯和小锐之间的最短关系路径

 

 

 

Spring-Boot使用neo4j-java-driver-- 查找两个节点之间关系的最短路径_第2张图片

 

 

        如上图,假设给你两个人,一个人是节点小讯,另一个人是节点小锐,问他们之间的关系最短路径是什么? 或者换句话问,小讯怎么用最少的步骤联系到小锐?【前提是,小讯和小锐之间不存在任何关系,否则这种问题就没有任何意义了,你俩都有关系了,我还问个毛啊,】

 

       如果你用肉眼观察的话,你会找到很多种小讯到达小锐的路径,比如:

1、小讯认识小峰,小菲认识小峰(如果不考虑关系的反向,则认为小峰也同样认识小菲),小菲又认识小唯,小唯认识小锐

因此这种路径下小讯联系小锐的步骤为: 小讯--小峰--小菲--小唯--小锐,路径长度4

2、同上,我们还可以找出一条长度等于3的路径:小讯--小林--小东--小锐

 

...... 等等,如果光靠肉眼观察的话,像这种数据少的话,勉强还可以捋下来,但是数据一多,就歇菜了,我们可以用neo4j自带的方法来算出两个节点之间存在关系的前提下的最短到达路径Path,比如:

 

查询出所有小讯到小锐的关系最短路径,语句如下:

 

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

 

查询出的graph效果如下:

 

下图标注的序号正是上面我们提到的长度等于3的一条路径:小讯--小林--小东--小锐

 

Spring-Boot使用neo4j-java-driver-- 查找两个节点之间关系的最短路径_第3张图片

 

 

如果我们只查出最短的一条路径,我们使用shortestPath的时候只会查出一条结果,不管结果怎么样,反正都是最短路径!

 

语句如下:

 

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

 

Spring-Boot使用neo4j-java-driver-- 查找两个节点之间关系的最短路径_第4张图片

 

 

 

四、找出小讯和小锐之间的深度等于4的路径Path

 

 

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

 

 

Spring-Boot使用neo4j-java-driver-- 查找两个节点之间关系的最短路径_第5张图片

 

 

 

 

如果你查找length(path) = 8的结果会怎么样呢?

 

Spring-Boot使用neo4j-java-driver-- 查找两个节点之间关系的最短路径_第6张图片

 

 

 

 

 

五、demo实现最短路径信息输出

 

 



Spring-Boot pom依赖

 

 

 


	4.0.0
	com.appleyk
	Spring-Boot-Neo4jAPI
	0.0.1-SNAPSHOT
	war
	Spring-Boot 集成Neo4j,实现原生JavaAPI的节点、关系操作
	
		org.springframework.boot
		spring-boot-starter-parent
		1.5.12.RELEASE
	
	
		1.8
		3.0.8
	
	
		
			org.springframework.boot
			spring-boot-starter-web
		
		
		
		
		
			org.springframework.boot
			spring-boot-devtools
			
			
			true
		
		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		
		
		
			junit
			junit
		
		
		
			org.neo4j.driver
			neo4j-java-driver
			1.6.1
		
	

 

 

 

demo演示:

 

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.neo4j.driver.v1.AuthTokens;
import org.neo4j.driver.v1.Driver;
import org.neo4j.driver.v1.GraphDatabase;
import org.neo4j.driver.v1.Record;
import org.neo4j.driver.v1.Session;
import org.neo4j.driver.v1.StatementResult;
import org.neo4j.driver.v1.Value;
import org.neo4j.driver.v1.types.Node;
import org.neo4j.driver.v1.types.Path;
import org.neo4j.driver.v1.types.Relationship;

public class Neo4jBatchTest {

	Driver driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.basic("neo4j", "n123"));
	private Session session = driver.session();

	/**
	 * 批量创建
	 * 
	 * @throws Exception
	 */
	@Test
	public void shortEstPath() throws Exception {
		try {
			String cmdSql = "MATCH n=shortestPath((a:朋友圈{姓名:'小讯'})-[*]-"
					+ "(b:朋友圈{姓名:'小锐'})) return n";
			StatementResult result = session.run(cmdSql);
			while (result.hasNext()) {
				Record record = result.next();
				List values = record.values();
				Map nodesMap = new HashMap<>();
				for (Value value : values) {
					if (value.type().name().equals("PATH")) {
						Path p = value.asPath();
						System.out.println("小讯和小锐之间的关系最短路径长度为:" + p.length());
						System.out.println("====================================");
						Iterable nodes = p.nodes();
						for (Node node : nodes) {
							nodesMap.put(node.id(), node);
						}

						/**
						 * 打印最短路径里面的关系 == 关系包括起始节点的ID和末尾节点的ID,以及关系的type类型
						 */
						Iterable relationships = p.relationships();
						for (Relationship relationship : relationships) {
							Long startID = relationship.startNodeId();
							Long endID = relationship.endNodeId();
							String rType = relationship.type();
							/**
							 * asMap 相当于 节点的properties属性信息
							 */
							System.out.println(
									nodesMap.get(startID).asMap() + "-" + rType + "-" 
							+ nodesMap.get(endID).asMap());
						}
					}
				}
			}
		} catch (Exception e) {
			System.err.println(e.getClass() + "," + e.getMessage());
		}
	}

}

 

 

运行方法效果如下:

 

 

Spring-Boot使用neo4j-java-driver-- 查找两个节点之间关系的最短路径_第7张图片

 

 

如果多条的话就:

 

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

 

执行结果:

 

Spring-Boot使用neo4j-java-driver-- 查找两个节点之间关系的最短路径_第8张图片

 

对比下,在neo4j中查询的结果

 

 

Spring-Boot使用neo4j-java-driver-- 查找两个节点之间关系的最短路径_第9张图片

你可能感兴趣的:(neo4j最短路径,neo4j,shortestpath,Spring-Boot,Neo4j)