一、Cypher數據
-
create (小北:朋友圈{姓名:
"小北", 喜歡的書類:
"Poetry"}),
-
(小菲:朋友圈{姓名:
"小菲", 喜歡的書類:
"Science Fiction"}),
-
(小鵬:朋友圈{姓名:
"小鵬", 喜歡的書類:
"Music"}),
-
(小穎:朋友圈{姓名:
"小穎", 喜歡的書類:
"Politics"}),
-
(小蘭:朋友圈{姓名:
"小蘭", 喜歡的書類:
"Music"}),
-
(小峰:朋友圈{姓名:
"小峰", 喜歡的書類:
"Travel"}),
-
(小訊:朋友圈{姓名:
"小訊", 喜歡的書類:
"Poetry"}),
-
(小東:朋友圈{姓名:
"小東", 喜歡的書類:
"Sequential Art"}),
-
(小唯:朋友圈{姓名:
"小唯", 喜歡的書類:
"Young Adult"}),
-
(小竇:朋友圈{姓名:
"小竇", 喜歡的書類:
"Poetry"}),
-
(小齊:朋友圈{姓名:
"小齊", 喜歡的書類:
"Default"}),
-
(小林:朋友圈{姓名:
"小林", 喜歡的書類:
"Poetry"}),
-
(小銳:朋友圈{姓名:
"小銳", 喜歡的書類:
"Default"}),
-
(小偉:朋友圈{姓名:
"小偉", 喜歡的書類:
"Young Adult"}),
-
(小玲:朋友圈{姓名:
"小玲", 喜歡的書類:
"Business"}),
-
(小訊)-[:認識]->(小竇),
-
(小訊)-[:認識]->(小齊),
-
(小訊)-[:認識]->(小林),
-
(小訊)-[:認識]->(小鵬),
-
(小訊)-[:認識]->(小偉),
-
(小訊)-[:認識]->(小峰),
-
(小菲)-[:認識]->(小鵬),
-
(小菲)-[:認識]->(小峰),
-
(小菲)-[:認識]->(小唯),
-
(小峰)-[:認識]->(小北),
-
(小峰)-[:認識]->(小蘭),
-
(小東)-[:認識]->(小林),
-
(小東)-[:認識]->(小銳),
-
(小東)-[:認識]->(小菲),
-
(小鵬)-[:認識]->(小穎),
-
(小北)-[:認識]->(小蘭),
-
(小穎)-[:認識]->(小東),
-
(小唯)-[:認識]->(小鵬),
-
(小唯)-[:認識]->(小銳),
-
(小偉)-[:認識]->(小玲)
二、執行后,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依賴
-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
<modelVersion>4.0.0
</modelVersion>
-
<groupId>com.appleyk
</groupId>
-
<artifactId>Spring-Boot-Neo4jAPI
</artifactId>
-
<version>0.0.1-SNAPSHOT
</version>
-
<packaging>war
</packaging>
-
<description>Spring-Boot 集成Neo4j,實現原生JavaAPI的節點、關系操作
</description>
-
<parent>
-
<groupId>org.springframework.boot
</groupId>
-
<artifactId>spring-boot-starter-parent
</artifactId>
-
<version>1.5.12.RELEASE
</version>
-
</parent>
-
<properties>
-
<java.version>1.8
</java.version>
-
<janino.version>3.0.8
</janino.version>
-
</properties>
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework.boot
</groupId>
-
<artifactId>spring-boot-starter-web
</artifactId>
-
</dependency>
-
<!-- 添加熱部署 devtools:監聽文件變動 -->
-
<!-- 當Java文件改動時,Spring-boo會快速重新啟動 -->
-
<!-- 最簡單的測試,就是隨便找一個文件Ctrl+S一下,就可以看到效果 -->
-
<dependency>
-
<groupId>org.springframework.boot
</groupId>
-
<artifactId>spring-boot-devtools
</artifactId>
-
<!-- optional=true,依賴不會傳遞 -->
-
<!-- 本項目依賴devtools;若依賴本項目的其他項目想要使用devtools,需要重新引入 -->
-
<optional>true
</optional>
-
</dependency>
-
<!-- Spring 單元測試 -->
-
<dependency>
-
<groupId>org.springframework.boot
</groupId>
-
<artifactId>spring-boot-starter-test
</artifactId>
-
<scope>test
</scope>
-
</dependency>
-
<!-- JUnit單元測試 -->
-
<dependency>
-
<groupId>junit
</groupId>
-
<artifactId>junit
</artifactId>
-
</dependency>
-
<!-- https://mvnrepository.com/artifact/org.neo4j.driver/neo4j-java-driver -->
-
<dependency>
-
<groupId>org.neo4j.driver
</groupId>
-
<artifactId>neo4j-java-driver
</artifactId>
-
<version>1.6.1
</version>
-
</dependency>
-
</dependencies>
-
</project>
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<
Value> values = record.values();
-
Map<
Long,
Node> 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<
Node> nodes = p.nodes();
-
for (
Node node : nodes) {
-
nodesMap.put(node.id(), node);
-
}
-
-
/**
-
* 打印最短路徑里面的關系 == 關系包括起始節點的ID和末尾節點的ID,以及關系的type類型
-
*/
-
Iterable<
Relationship> 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());
-
}
-
}
-
-
}
運行方法效果如下:
如果多條的話就:
String cmdSql = "MATCH n=allshortestPaths((a:朋友圈{姓名:'小訊'})-[*]-(b:朋友圈{姓名:'小銳'})) return n";
執行結果:
對比下,在neo4j中查詢的結果