当前位置:   article > 正文

Spring Boot2 集成 Neo4j 实现知识图谱_java 集成neo4j 实现知识图谱

java 集成neo4j 实现知识图谱

一 Neo4j 简介

Neo4j是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。程序员工作在一个面向对象的、灵活的网络结构下而不是严格、静态的表中——但是他们可以享受到具备完全的事务特性、企业级的数据库的所有好处。

1.1 图形数据结构

在一个图中包含两种基本的数据类型:Nodes(节点) 和 Relationships(关系)。Nodes 和 Relationships 包含key/value形式的属性。Nodes通过Relationships所定义的关系相连起来,形成关系型网络结构。

1.2 安装Neo4j

1.2.1 下载安装包

liunx环境Neo4j下载地址:https://neo4j.com/download/other-releases/#releases(社区版免费)

注意:下载各自系统所需版本tar即可,我是Centos系统,故下载的是liunx版本,4.X后需要JDK11版本,3.X需要JDK8

1.2.2 上传下载的tar包,进行解压

tar -zxvf neo4j-community-3.4.5-unix.tar.gz

1.2.3 修改配置文件

在安装目录下找到conf目录下的neo4j.conf文件

vim neo4j.conf

修改相应配置如下:

1.2.4 常用命令

进入bin目录执行命令

启动命令:./neo4j start

停止命令:./neo4j stop

查看图数据库状态:./neo4j status

1.2.5 客户端访问

http://服务器ip地址:7474/browser/

在浏览器访问图数据库所在的机器上的7474端口(第一次访问账号neo4j,密码neo4j,会提示修改初始密码)

二 Spring Boot2 集成 Neo4j

Spring Boo2版本为:2.0.6

2.1 pom.xml依赖

  1. <!-- neo4j-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-data-neo4j</artifactId>
  5. </dependency>
  6. <!-- neo4j driver驱动-->
  7. <dependency>
  8. <groupId>org.neo4j.driver</groupId>
  9. <artifactId>neo4j-java-driver</artifactId>
  10. <version>1.7.5</version>
  11. </dependency>

完整pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.0.6.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.modules</groupId>
  12. <artifactId>spring-boot2-neo4j</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>spring-boot2-neo4j</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>1.8</java.version>
  18. <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
  19. </properties>
  20. <dependencies>
  21. <!-- spring boot2 核心-->
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter</artifactId>
  25. </dependency>
  26. <!-- spring boot2 web-->
  27. <dependency>
  28. <groupId>org.springframework.boot</groupId>
  29. <artifactId>spring-boot-starter-web</artifactId>
  30. </dependency>
  31. <!-- devtools-->
  32. <dependency>
  33. <groupId>org.springframework.boot</groupId>
  34. <artifactId>spring-boot-devtools</artifactId>
  35. <scope>runtime</scope>
  36. <optional>true</optional>
  37. </dependency>
  38. <!-- test-->
  39. <dependency>
  40. <groupId>org.springframework.boot</groupId>
  41. <artifactId>spring-boot-starter-test</artifactId>
  42. <scope>test</scope>
  43. </dependency>
  44. <!-- neo4j-->
  45. <dependency>
  46. <groupId>org.springframework.boot</groupId>
  47. <artifactId>spring-boot-starter-data-neo4j</artifactId>
  48. </dependency>
  49. <!-- neo4j driver驱动-->
  50. <dependency>
  51. <groupId>org.neo4j.driver</groupId>
  52. <artifactId>neo4j-java-driver</artifactId>
  53. <version>1.7.5</version>
  54. </dependency>
  55. <!-- fastjson -->
  56. <dependency>
  57. <groupId>com.alibaba</groupId>
  58. <artifactId>fastjson</artifactId>
  59. <version>1.2.58</version>
  60. </dependency>
  61. <!-- lombok -->
  62. <dependency>
  63. <groupId>org.projectlombok</groupId>
  64. <artifactId>lombok</artifactId>
  65. </dependency>
  66. <!-- swagger2-->
  67. <dependency>
  68. <groupId>io.springfox</groupId>
  69. <artifactId>springfox-swagger2</artifactId>
  70. <version>2.9.2</version>
  71. <exclusions>
  72. <exclusion>
  73. <groupId>io.swagger</groupId>
  74. <artifactId>swagger-annotations</artifactId>
  75. </exclusion>
  76. <exclusion>
  77. <groupId>io.swagger</groupId>
  78. <artifactId>swagger-models</artifactId>
  79. </exclusion>
  80. </exclusions>
  81. </dependency>
  82. <!-- swagger2-UI-->
  83. <dependency>
  84. <groupId>io.springfox</groupId>
  85. <artifactId>springfox-swagger-ui</artifactId>
  86. <version>2.9.2</version>
  87. </dependency>
  88. <!--防止进入swagger页面报类型转换错误,排除2.9.2中的引用,手动增加1.5.21版本-->
  89. <dependency>
  90. <groupId>io.swagger</groupId>
  91. <artifactId>swagger-annotations</artifactId>
  92. <version>1.5.21</version>
  93. </dependency>
  94. <dependency>
  95. <groupId>io.swagger</groupId>
  96. <artifactId>swagger-models</artifactId>
  97. <version>1.5.21</version>
  98. </dependency>
  99. </dependencies>
  100. <!-- 依赖版本管理 -->
  101. <dependencyManagement>
  102. <dependencies>
  103. <dependency>
  104. <groupId>org.springframework.cloud</groupId>
  105. <artifactId>spring-cloud-dependencies</artifactId>
  106. <version>${spring-cloud.version}</version>
  107. <type>pom</type>
  108. <scope>import</scope>
  109. </dependency>
  110. </dependencies>
  111. </dependencyManagement>
  112. <build>
  113. <plugins>
  114. <plugin>
  115. <groupId>org.springframework.boot</groupId>
  116. <artifactId>spring-boot-maven-plugin</artifactId>
  117. <!-- 引入系统范围内的依赖 -->
  118. <configuration>
  119. <includeSystemScope>true</includeSystemScope>
  120. </configuration>
  121. </plugin>
  122. <!--添加配置跳过测试-->
  123. <plugin>
  124. <groupId>org.apache.maven.plugins</groupId>
  125. <artifactId>maven-surefire-plugin</artifactId>
  126. <version>2.22.2</version>
  127. <configuration>
  128. <skipTests>true</skipTests>
  129. </configuration>
  130. </plugin>
  131. </plugins>
  132. </build>
  133. </project>

2.2 application.properties配置

  1. server.port=8088
  2. server.servlet.context-path=/neo4j
  3. # 启用优雅关机
  4. server.shutdown=graceful
  5. # 缓冲10
  6. spring.lifecycle.timeout-per-shutdown-phase=10s
  7. # neo4j配置
  8. spring.data.neo4j.uri= bolt://172.16.21.201:7687
  9. spring.data.neo4j.username=neo4j
  10. spring.data.neo4j.password=111111
  11. #日志配置
  12. logging.level.com.modules.project.dao=debug
  13. # 设置时间
  14. spring.jackson.time-zone=GMT+8
  15. # 全局格式化日期
  16. spring.jackson.date-format=yyyy-MM-dd HH:mm:ss

2.3 Neo4j 配置类

  1. package com.modules.common.config;
  2. import org.neo4j.driver.v1.AuthTokens;
  3. import org.neo4j.driver.v1.Driver;
  4. import org.neo4j.driver.v1.GraphDatabase;
  5. import org.springframework.beans.factory.annotation.Value;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. /**
  9. * neo4j图数据库配置
  10. *
  11. * @author li'chao
  12. */
  13. @Configuration
  14. public class Neo4jConfig {
  15. @Value("${spring.data.neo4j.uri}")
  16. private String url;
  17. @Value("${spring.data.neo4j.username}")
  18. private String username;
  19. @Value("${spring.data.neo4j.password}")
  20. private String password;
  21. /**
  22. * neo4j图数据库驱动模式
  23. *
  24. * @return
  25. */
  26. @Bean
  27. public Driver neo4jDriver() {
  28. return GraphDatabase.driver(url, AuthTokens.basic(username, password));
  29. }
  30. }

2.4 Neo4jUtil工具类

  1. package com.modules.common.utils;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.neo4j.driver.v1.*;
  4. import org.neo4j.driver.v1.types.Node;
  5. import org.neo4j.driver.v1.types.Path;
  6. import org.neo4j.driver.v1.types.Relationship;
  7. import org.neo4j.driver.v1.util.Pair;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.stereotype.Component;
  10. import java.lang.reflect.Field;
  11. import java.util.*;
  12. import java.util.Map.Entry;
  13. @Slf4j
  14. @Component
  15. public class Neo4jUtil {
  16. @Autowired
  17. private Driver neo4jDriver;
  18. public boolean isNeo4jOpen() {
  19. try (Session session = neo4jDriver.session()) {
  20. log.info("连接成功:" + session.isOpen());
  21. return session.isOpen();
  22. } catch (Exception e) {
  23. log.error("连接异常:" + e.getMessage());
  24. return false;
  25. }
  26. }
  27. public StatementResult excuteCypherSql(String cypherSql) {
  28. StatementResult result = null;
  29. try (Session session = neo4jDriver.session()) {
  30. log.info("cypher语句:" + cypherSql);
  31. result = session.run(cypherSql);
  32. session.close();
  33. } catch (Exception e) {
  34. throw e;
  35. }
  36. return result;
  37. }
  38. public HashMap<String, Object> getEntityMap(String cypherSql) {
  39. HashMap<String, Object> rss = new HashMap<String, Object>();
  40. try {
  41. StatementResult result = excuteCypherSql(cypherSql);
  42. if (result.hasNext()) {
  43. List<Record> records = result.list();
  44. for (Record recordItem : records) {
  45. for (Value value : recordItem.values()) {
  46. if (value.type().name().equals("NODE")) {// 结果里面只要类型为节点的值
  47. Node noe4jNode = value.asNode();
  48. Map<String, Object> map = noe4jNode.asMap();
  49. for (Entry<String, Object> entry : map.entrySet()) {
  50. String key = entry.getKey();
  51. if (rss.containsKey(key)) {
  52. String oldValue = rss.get(key).toString();
  53. String newValue = oldValue + "," + entry.getValue();
  54. rss.replace(key, newValue);
  55. } else {
  56. rss.put(key, entry.getValue());
  57. }
  58. }
  59. }
  60. }
  61. }
  62. }
  63. } catch (Exception e) {
  64. e.printStackTrace();
  65. }
  66. return rss;
  67. }
  68. public List<HashMap<String, Object>> getGraphNode(String cypherSql) {
  69. List<HashMap<String, Object>> ents = new ArrayList<HashMap<String, Object>>();
  70. try {
  71. StatementResult result = excuteCypherSql(cypherSql);
  72. if (result.hasNext()) {
  73. List<Record> records = result.list();
  74. for (Record recordItem : records) {
  75. List<Pair<String, Value>> f = recordItem.fields();
  76. for (Pair<String, Value> pair : f) {
  77. HashMap<String, Object> rss = new HashMap<String, Object>();
  78. String typeName = pair.value().type().name();
  79. if (typeName.equals("NODE")) {
  80. Node noe4jNode = pair.value().asNode();
  81. String uuid = String.valueOf(noe4jNode.id());
  82. Map<String, Object> map = noe4jNode.asMap();
  83. for (Entry<String, Object> entry : map.entrySet()) {
  84. String key = entry.getKey();
  85. rss.put(key, entry.getValue());
  86. }
  87. rss.put("uuid", uuid);
  88. ents.add(rss);
  89. }
  90. }
  91. }
  92. }
  93. } catch (Exception e) {
  94. e.printStackTrace();
  95. }
  96. return ents;
  97. }
  98. public List<HashMap<String, Object>> getGraphRelationShip(String cypherSql) {
  99. List<HashMap<String, Object>> ents = new ArrayList<HashMap<String, Object>>();
  100. try {
  101. StatementResult result = excuteCypherSql(cypherSql);
  102. if (result.hasNext()) {
  103. List<Record> records = result.list();
  104. for (Record recordItem : records) {
  105. List<Pair<String, Value>> f = recordItem.fields();
  106. for (Pair<String, Value> pair : f) {
  107. HashMap<String, Object> rss = new HashMap<String, Object>();
  108. String typeName = pair.value().type().name();
  109. if (typeName.equals("RELATIONSHIP")) {
  110. Relationship rship = pair.value().asRelationship();
  111. String uuid = String.valueOf(rship.id());
  112. String sourceid = String.valueOf(rship.startNodeId());
  113. String targetid = String.valueOf(rship.endNodeId());
  114. Map<String, Object> map = rship.asMap();
  115. for (Entry<String, Object> entry : map.entrySet()) {
  116. String key = entry.getKey();
  117. rss.put(key, entry.getValue());
  118. }
  119. rss.put("uuid", uuid);
  120. rss.put("sourceid", sourceid);
  121. rss.put("targetid", targetid);
  122. ents.add(rss);
  123. }
  124. }
  125. }
  126. }
  127. } catch (Exception e) {
  128. e.printStackTrace();
  129. }
  130. return ents;
  131. }
  132. public List<HashMap<String, Object>> getGraphItem(String cypherSql) {
  133. List<HashMap<String, Object>> ents = new ArrayList<HashMap<String, Object>>();
  134. List<String> nodeids = new ArrayList<String>();
  135. List<String> shipids = new ArrayList<String>();
  136. try {
  137. StatementResult result = excuteCypherSql(cypherSql);
  138. if (result.hasNext()) {
  139. List<Record> records = result.list();
  140. for (Record recordItem : records) {
  141. List<Pair<String, Value>> f = recordItem.fields();
  142. HashMap<String, Object> rss = new HashMap<String, Object>();
  143. for (Pair<String, Value> pair : f) {
  144. String typeName = pair.value().type().name();
  145. if (typeName.equals("NODE")) {
  146. Node noe4jNode = pair.value().asNode();
  147. String uuid = String.valueOf(noe4jNode.id());
  148. if(!nodeids.contains(uuid)) {
  149. Map<String, Object> map = noe4jNode.asMap();
  150. for (Entry<String, Object> entry : map.entrySet()) {
  151. String key = entry.getKey();
  152. rss.put(key, entry.getValue());
  153. }
  154. rss.put("uuid", uuid);
  155. }
  156. }else if (typeName.equals("RELATIONSHIP")) {
  157. Relationship rship = pair.value().asRelationship();
  158. String uuid = String.valueOf(rship.id());
  159. if (!shipids.contains(uuid)) {
  160. String sourceid = String.valueOf(rship.startNodeId());
  161. String targetid = String.valueOf(rship.endNodeId());
  162. Map<String, Object> map = rship.asMap();
  163. for (Entry<String, Object> entry : map.entrySet()) {
  164. String key = entry.getKey();
  165. rss.put(key, entry.getValue());
  166. }
  167. rss.put("uuid", uuid);
  168. rss.put("sourceid", sourceid);
  169. rss.put("targetid", targetid);
  170. }
  171. }else {
  172. rss.put(pair.key(),pair.value().toString());
  173. }
  174. }
  175. ents.add(rss);
  176. }
  177. }
  178. } catch (Exception e) {
  179. e.printStackTrace();
  180. }
  181. return ents;
  182. }
  183. /*
  184. * 获取值类型的结果,如count,uuid
  185. * @return 1 2 3 等数字类型
  186. */
  187. public long getGraphValue(String cypherSql) {
  188. long val=0;
  189. try {
  190. StatementResult cypherResult = excuteCypherSql(cypherSql);
  191. if (cypherResult.hasNext()) {
  192. Record record = cypherResult.next();
  193. for (Value value : record.values()) {
  194. val = value.asLong();
  195. }
  196. }
  197. } catch (Exception e) {
  198. e.printStackTrace();
  199. }
  200. return val;
  201. }
  202. public HashMap<String, Object> getGraphNodeAndShip(String cypherSql) {
  203. HashMap<String, Object> mo = new HashMap<String, Object>();
  204. try {
  205. StatementResult result = excuteCypherSql(cypherSql);
  206. if (result.hasNext()) {
  207. List<Record> records = result.list();
  208. List<HashMap<String, Object>> ents = new ArrayList<HashMap<String, Object>>();
  209. List<HashMap<String, Object>> ships = new ArrayList<HashMap<String, Object>>();
  210. List<String> uuids = new ArrayList<String>();
  211. List<String> shipids = new ArrayList<String>();
  212. for (Record recordItem : records) {
  213. List<Pair<String, Value>> f = recordItem.fields();
  214. for (Pair<String, Value> pair : f) {
  215. HashMap<String, Object> rships = new HashMap<String, Object>();
  216. HashMap<String, Object> rss = new HashMap<String, Object>();
  217. String typeName = pair.value().type().name();
  218. if (typeName.equals("NULL")) {
  219. continue;
  220. } else if (typeName.equals("NODE")) {
  221. Node noe4jNode = pair.value().asNode();
  222. Map<String, Object> map = noe4jNode.asMap();
  223. String uuid = String.valueOf(noe4jNode.id());
  224. if (!uuids.contains(uuid)) {
  225. for (Entry<String, Object> entry : map.entrySet()) {
  226. String key = entry.getKey();
  227. rss.put(key, entry.getValue());
  228. }
  229. rss.put("uuid", uuid);
  230. uuids.add(uuid);
  231. }
  232. if (rss != null && !rss.isEmpty()) {
  233. ents.add(rss);
  234. }
  235. } else if (typeName.equals("RELATIONSHIP")) {
  236. Relationship rship = pair.value().asRelationship();
  237. String uuid = String.valueOf(rship.id());
  238. if (!shipids.contains(uuid)) {
  239. String sourceid = String.valueOf(rship.startNodeId());
  240. String targetid = String.valueOf(rship.endNodeId());
  241. Map<String, Object> map = rship.asMap();
  242. for (Entry<String, Object> entry : map.entrySet()) {
  243. String key = entry.getKey();
  244. rships.put(key, entry.getValue());
  245. }
  246. rships.put("uuid", uuid);
  247. rships.put("sourceid", sourceid);
  248. rships.put("targetid", targetid);
  249. shipids.add(uuid);
  250. if (rships != null && !rships.isEmpty()) {
  251. ships.add(rships);
  252. }
  253. }
  254. } else if (typeName.equals("PATH")) {
  255. Path path = pair.value().asPath();
  256. Map<String, Object> startNodemap = path.start().asMap();
  257. String startNodeuuid = String.valueOf(path.start().id());
  258. if (!uuids.contains(startNodeuuid)) {
  259. rss=new HashMap<String, Object>();
  260. for (Entry<String, Object> entry : startNodemap.entrySet()) {
  261. String key = entry.getKey();
  262. rss.put(key, entry.getValue());
  263. }
  264. rss.put("uuid", startNodeuuid);
  265. uuids.add(startNodeuuid);
  266. if (rss != null && !rss.isEmpty()) {
  267. ents.add(rss);
  268. }
  269. }
  270. Map<String, Object> endNodemap = path.end().asMap();
  271. String endNodeuuid = String.valueOf(path.end().id());
  272. if (!uuids.contains(endNodeuuid)) {
  273. rss=new HashMap<String, Object>();
  274. for (Entry<String, Object> entry : endNodemap.entrySet()) {
  275. String key = entry.getKey();
  276. rss.put(key, entry.getValue());
  277. }
  278. rss.put("uuid", endNodeuuid);
  279. uuids.add(endNodeuuid);
  280. if (rss != null && !rss.isEmpty()) {
  281. ents.add(rss);
  282. }
  283. }
  284. Iterator<Node> allNodes = path.nodes().iterator();
  285. while (allNodes.hasNext()) {
  286. Node next = allNodes.next();
  287. String uuid = String.valueOf(next.id());
  288. if (!uuids.contains(uuid)) {
  289. rss=new HashMap<String, Object>();
  290. Map<String, Object> map = next.asMap();
  291. for (Entry<String, Object> entry : map.entrySet()) {
  292. String key = entry.getKey();
  293. rss.put(key, entry.getValue());
  294. }
  295. rss.put("uuid", uuid);
  296. uuids.add(uuid);
  297. if (rss != null && !rss.isEmpty()) {
  298. ents.add(rss);
  299. }
  300. }
  301. }
  302. Iterator<Relationship> reships = path.relationships().iterator();
  303. while (reships.hasNext()) {
  304. Relationship next = reships.next();
  305. String uuid = String.valueOf(next.id());
  306. if (!shipids.contains(uuid)) {
  307. rships=new HashMap<String, Object>();
  308. String sourceid = String.valueOf(next.startNodeId());
  309. String targetid = String.valueOf(next.endNodeId());
  310. Map<String, Object> map = next.asMap();
  311. for (Entry<String, Object> entry : map.entrySet()) {
  312. String key = entry.getKey();
  313. rships.put(key, entry.getValue());
  314. }
  315. rships.put("uuid", uuid);
  316. rships.put("sourceid", sourceid);
  317. rships.put("targetid", targetid);
  318. shipids.add(uuid);
  319. if (rships != null && !rships.isEmpty()) {
  320. ships.add(rships);
  321. }
  322. }
  323. }
  324. } else if (typeName.contains("LIST")) {
  325. Iterable<Value> val=pair.value().values();
  326. Value next = val.iterator().next();
  327. String type=next.type().name();
  328. if (type.equals("RELATIONSHIP")) {
  329. Relationship rship = next.asRelationship();
  330. String uuid = String.valueOf(rship.id());
  331. if (!shipids.contains(uuid)) {
  332. String sourceid = String.valueOf(rship.startNodeId());
  333. String targetid = String.valueOf(rship.endNodeId());
  334. Map<String, Object> map = rship.asMap();
  335. for (Entry<String, Object> entry : map.entrySet()) {
  336. String key = entry.getKey();
  337. rships.put(key, entry.getValue());
  338. }
  339. rships.put("uuid", uuid);
  340. rships.put("sourceid", sourceid);
  341. rships.put("targetid", targetid);
  342. shipids.add(uuid);
  343. if (rships != null && !rships.isEmpty()) {
  344. ships.add(rships);
  345. }
  346. }
  347. }
  348. } else if (typeName.contains("MAP")) {
  349. rss.put(pair.key(), pair.value().asMap());
  350. } else {
  351. rss.put(pair.key(), pair.value().toString());
  352. if (rss != null && !rss.isEmpty()) {
  353. ents.add(rss);
  354. }
  355. }
  356. }
  357. }
  358. mo.put("node", ents);
  359. mo.put("relationship", ships);
  360. }
  361. } catch (Exception e) {
  362. throw new RuntimeException("执行Cypher查询异常");
  363. }
  364. return mo;
  365. }
  366. /**
  367. * 匹配所有类型的节点,可以是节点,关系,数值,路径
  368. * @param cypherSql
  369. * @return
  370. */
  371. public List<HashMap<String, Object>> getEntityList(String cypherSql) {
  372. List<HashMap<String, Object>> ents = new ArrayList<HashMap<String, Object>>();
  373. try {
  374. StatementResult result = excuteCypherSql(cypherSql);
  375. if (result.hasNext()) {
  376. List<Record> records = result.list();
  377. for (Record recordItem : records) {
  378. HashMap<String, Object> rss = new HashMap<String, Object>();
  379. List<Pair<String, Value>> f = recordItem.fields();
  380. for (Pair<String, Value> pair : f) {
  381. String typeName = pair.value().type().name();
  382. if (typeName.equals("NULL")) {
  383. continue;
  384. } else if (typeName.equals("NODE")) {
  385. Node noe4jNode = pair.value().asNode();
  386. Map<String, Object> map = noe4jNode.asMap();
  387. for (Entry<String, Object> entry : map.entrySet()) {
  388. String key = entry.getKey();
  389. rss.put(key, entry.getValue());
  390. }
  391. } else if (typeName.equals("RELATIONSHIP")) {
  392. Relationship rship = pair.value().asRelationship();
  393. Map<String, Object> map = rship.asMap();
  394. for (Entry<String, Object> entry : map.entrySet()) {
  395. String key = entry.getKey();
  396. rss.put(key, entry.getValue());
  397. }
  398. } else if (typeName.equals("PATH")) {
  399. } else if (typeName.contains("LIST")) {
  400. rss.put(pair.key(), pair.value().asList());
  401. } else if (typeName.contains("MAP")) {
  402. rss.put(pair.key(), pair.value().asMap());
  403. } else {
  404. rss.put(pair.key(), pair.value().toString());
  405. }
  406. }
  407. ents.add(rss);
  408. }
  409. }
  410. } catch (Exception e) {
  411. e.printStackTrace();
  412. }
  413. return ents;
  414. }
  415. public <T> List<T> getEntityItemList(String cypherSql, Class<T> type) {
  416. List<HashMap<String, Object>> ents = getGraphNode(cypherSql);
  417. List<T> model = hashMapToObject(ents, type);
  418. return model;
  419. }
  420. public <T> T getEntityItem(String cypherSql, Class<T> type) {
  421. HashMap<String, Object> rss = new HashMap<String, Object>();
  422. try {
  423. StatementResult result = excuteCypherSql(cypherSql);
  424. if (result.hasNext()) {
  425. Record record = result.next();
  426. for (Value value : record.values()) {
  427. if (value.type().name().equals("NODE")) {// 结果里面只要类型为节点的值
  428. Node noe4jNode = value.asNode();
  429. Map<String, Object> map = noe4jNode.asMap();
  430. for (Entry<String, Object> entry : map.entrySet()) {
  431. String key = entry.getKey();
  432. if (rss.containsKey(key)) {
  433. String oldValue = rss.get(key).toString();
  434. String newValue = oldValue + "," + entry.getValue();
  435. rss.replace(key, newValue);
  436. } else {
  437. rss.put(key, entry.getValue());
  438. }
  439. }
  440. }
  441. }
  442. }
  443. } catch (Exception e) {
  444. e.printStackTrace();
  445. }
  446. T model = hashMapToObjectItem(rss, type);
  447. return model;
  448. }
  449. public HashMap<String, Object> getEntity(String cypherSql) {
  450. HashMap<String, Object> rss = new HashMap<String, Object>();
  451. try {
  452. StatementResult result = excuteCypherSql(cypherSql);
  453. if (result.hasNext()) {
  454. Record record = result.next();
  455. for (Value value : record.values()) {
  456. String t = value.type().name();
  457. if (value.type().name().equals("NODE")) {// 结果里面只要类型为节点的值
  458. Node noe4jNode = value.asNode();
  459. Map<String, Object> map = noe4jNode.asMap();
  460. for (Entry<String, Object> entry : map.entrySet()) {
  461. String key = entry.getKey();
  462. if (rss.containsKey(key)) {
  463. String oldValue = rss.get(key).toString();
  464. String newValue = oldValue + "," + entry.getValue();
  465. rss.replace(key, newValue);
  466. } else {
  467. rss.put(key, entry.getValue());
  468. }
  469. }
  470. }
  471. }
  472. }
  473. } catch (Exception e) {
  474. e.printStackTrace();
  475. }
  476. return rss;
  477. }
  478. public Integer executeScalar(String cypherSql) {
  479. Integer count = 0;
  480. try {
  481. StatementResult result = excuteCypherSql(cypherSql);
  482. if (result.hasNext()) {
  483. Record record = result.next();
  484. for (Value value : record.values()) {
  485. String t = value.type().name();
  486. if (t.equals("INTEGER")) {
  487. count = Integer.valueOf(value.toString());
  488. break;
  489. }
  490. }
  491. }
  492. } catch (Exception e) {
  493. e.printStackTrace();
  494. }
  495. return count;
  496. }
  497. public HashMap<String, Object> getRelevantEntity(String cypherSql) {
  498. HashMap<String, Object> rss = new HashMap<String, Object>();
  499. try {
  500. StatementResult resultNode = excuteCypherSql(cypherSql);
  501. if (resultNode.hasNext()) {
  502. List<Record> records = resultNode.list();
  503. for (Record recordItem : records) {
  504. Map<String, Object> r = recordItem.asMap();
  505. String key = r.get("key").toString();
  506. if (rss.containsKey(key)) {
  507. String oldValue = rss.get(key).toString();
  508. String newValue = oldValue + "," + r.get("value");
  509. rss.replace(key, newValue);
  510. } else {
  511. rss.put(key, r.get("value"));
  512. }
  513. }
  514. }
  515. } catch (Exception e) {
  516. e.printStackTrace();
  517. }
  518. return rss;
  519. }
  520. public String getFilterPropertiesJson(String jsonStr) {
  521. String propertiesString = jsonStr.replaceAll("\"(\\w+)\"(\\s*:\\s*)", "$1$2"); // 去掉key的引号
  522. return propertiesString;
  523. }
  524. public <T>String getkeyvalCyphersql(T obj) {
  525. Map<String, Object> map = new HashMap<String, Object>();
  526. List<String> sqlList=new ArrayList<String>();
  527. // 得到类对象
  528. Class userCla = obj.getClass();
  529. /* 得到类中的所有属性集合 */
  530. Field[] fs = userCla.getDeclaredFields();
  531. for (int i = 0; i < fs.length; i++) {
  532. Field f = fs[i];
  533. Class type = f.getType();
  534. f.setAccessible(true); // 设置些属性是可以访问的
  535. Object val = new Object();
  536. try {
  537. val = f.get(obj);
  538. if(val==null) {
  539. val="";
  540. }
  541. String sql="";
  542. String key=f.getName();
  543. log.info("key:"+key+"type:"+type);
  544. if ( val instanceof Integer ){
  545. // 得到此属性的值
  546. map.put(key, val);// 设置键值
  547. sql="n."+key+"="+val;
  548. }
  549. else if ( val instanceof String[] ){
  550. //如果为true则强转成String数组
  551. String [] arr = ( String[] ) val ;
  552. String v="";
  553. for ( int j = 0 ; j < arr.length ; j++ ){
  554. arr[j]="'"+ arr[j]+"'";
  555. }
  556. v=String.join(",", arr);
  557. sql="n."+key+"=["+val+"]";
  558. }
  559. else if (val instanceof List){
  560. //如果为true则强转成String数组
  561. List<String> arr = ( ArrayList<String> ) val ;
  562. List<String> aa=new ArrayList<String>();
  563. String v="";
  564. for (String s : arr) {
  565. s="'"+ s+"'";
  566. aa.add(s);
  567. }
  568. v=String.join(",", aa);
  569. sql="n."+key+"=["+v+"]";
  570. }
  571. else {
  572. // 得到此属性的值
  573. map.put(key, val);// 设置键值
  574. sql="n."+key+"='"+val+"'";
  575. }
  576. sqlList.add(sql);
  577. } catch (IllegalArgumentException e) {
  578. e.printStackTrace();
  579. } catch (IllegalAccessException e) {
  580. e.printStackTrace();
  581. }
  582. }
  583. String finasql=String.join(",",sqlList);
  584. log.info("单个对象的所有键值==反射==" + map.toString());
  585. return finasql;
  586. }
  587. public <T> List<T> hashMapToObject(List<HashMap<String, Object>> maps, Class<T> type) {
  588. try {
  589. List<T> list = new ArrayList<T>();
  590. for (HashMap<String, Object> r : maps) {
  591. T t = type.newInstance();
  592. Iterator iter = r.entrySet().iterator();// 该方法获取列名.获取一系列字段名称.例如name,age...
  593. while (iter.hasNext()) {
  594. Entry entry = (Entry) iter.next();// 把hashmap转成Iterator再迭代到entry
  595. String key = entry.getKey().toString(); // 从iterator遍历获取key
  596. Object value = entry.getValue(); // 从hashmap遍历获取value
  597. if("serialVersionUID".toLowerCase().equals(key.toLowerCase()))continue;
  598. Field field = type.getDeclaredField(key);// 获取field对象
  599. if (field != null) {
  600. field.setAccessible(true);
  601. if (field.getType() == int.class || field.getType() == Integer.class) {
  602. if (value==null||StringUtils.isBlank(value.toString())) {
  603. field.set(t, 0);// 设置值
  604. } else {
  605. field.set(t, Integer.parseInt(value.toString()));// 设置值
  606. }
  607. }
  608. else if (field.getType() == long.class||field.getType() == Long.class ) {
  609. if (value==null||StringUtils.isBlank(value.toString())) {
  610. field.set(t, 0);// 设置值
  611. } else {
  612. field.set(t, Long.parseLong(value.toString()));// 设置值
  613. }
  614. }
  615. else {
  616. field.set(t, value);// 设置值
  617. }
  618. }
  619. }
  620. list.add(t);
  621. }
  622. return list;
  623. } catch (Exception e) {
  624. throw new RuntimeException(e);
  625. }
  626. }
  627. public <T> T hashMapToObjectItem(HashMap<String, Object> map, Class<T> type) {
  628. try {
  629. T t = type.newInstance();
  630. Iterator iter = map.entrySet().iterator();
  631. while (iter.hasNext()) {
  632. Entry entry = (Entry) iter.next();// 把hashmap转成Iterator再迭代到entry
  633. String key = entry.getKey().toString(); // 从iterator遍历获取key
  634. Object value = entry.getValue(); // 从hashmap遍历获取value
  635. if("serialVersionUID".toLowerCase().equals(key.toLowerCase()))continue;
  636. Field field = type.getDeclaredField(key);// 获取field对象
  637. if (field != null) {
  638. field.setAccessible(true);
  639. if (field.getType() == int.class || field.getType() == Integer.class) {
  640. if (value==null||StringUtils.isBlank(value.toString())) {
  641. field.set(t, 0);// 设置值
  642. } else {
  643. field.set(t, Integer.parseInt(value.toString()));// 设置值
  644. }
  645. }
  646. else if (field.getType() == long.class||field.getType() == Long.class ) {
  647. if (value==null||StringUtils.isBlank(value.toString())) {
  648. field.set(t, 0);// 设置值
  649. } else {
  650. field.set(t, Long.parseLong(value.toString()));// 设置值
  651. }
  652. }
  653. else {
  654. field.set(t, value);// 设置值
  655. }
  656. }
  657. }
  658. return t;
  659. } catch (Exception e) {
  660. throw new RuntimeException(e);
  661. }
  662. }
  663. public List<String> getNodesLabelsEntityList(String cypherSql) {
  664. List<String> rss = new ArrayList<>();
  665. try {
  666. StatementResult resultNode = excuteCypherSql(cypherSql);
  667. if (resultNode.hasNext()) {
  668. List<Record> records = resultNode.list();
  669. for (Record recordItem : records) {
  670. Map<String, Object> r = recordItem.asMap();
  671. rss.add(r.get("label").toString());
  672. }
  673. }
  674. } catch (Exception e) {
  675. e.printStackTrace();
  676. }
  677. return rss;
  678. }
  679. public List<String> getRelationshipTypeEntityList(String cypherSql) {
  680. List<String> rss = new ArrayList<>();
  681. try {
  682. StatementResult resultNode = excuteCypherSql(cypherSql);
  683. if (resultNode.hasNext()) {
  684. List<Record> records = resultNode.list();
  685. for (Record recordItem : records) {
  686. Map<String, Object> r = recordItem.asMap();
  687. rss.add(r.get("relationshipType").toString());
  688. }
  689. }
  690. } catch (Exception e) {
  691. e.printStackTrace();
  692. }
  693. return rss;
  694. }
  695. }

2.5 实现图库数据查询功能

2.5.1 controller

  1. package com.modules.project.controller;
  2. import com.modules.common.utils.Neo4jUtil;
  3. import com.modules.common.web.BaseController;
  4. import com.modules.common.web.Result;
  5. import com.modules.project.entity.GraphQuery;
  6. import com.modules.project.service.GraphService;
  7. import io.swagger.annotations.Api;
  8. import io.swagger.annotations.ApiOperation;
  9. import lombok.extern.slf4j.Slf4j;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.validation.annotation.Validated;
  12. import org.springframework.web.bind.annotation.GetMapping;
  13. import org.springframework.web.bind.annotation.RequestMapping;
  14. import org.springframework.web.bind.annotation.RestController;
  15. import java.util.HashMap;
  16. import java.util.List;
  17. /**
  18. * neo4j图数据管理
  19. *
  20. * @author li'chao
  21. */
  22. @Api(tags = "neo4j图数据管理")
  23. @Slf4j
  24. @RestController
  25. @RequestMapping("/graph")
  26. public class GraphController extends BaseController {
  27. @Autowired
  28. private Neo4jUtil neo4jUtil;
  29. @Autowired
  30. private GraphService graphService;
  31. @ApiOperation(value = "执行Cypher查询", notes = "执行Cypher查询")
  32. @GetMapping(value = "/getCypherResult")
  33. public Result getCypherResult(String cypher) {
  34. try {
  35. HashMap<String, Object> graphData = neo4jUtil.getGraphNodeAndShip(cypher);
  36. return success(graphData);
  37. } catch (Exception e) {
  38. log.error("执行Cypher查询异常:" + e.getMessage());
  39. return error("执行Cypher查询异常");
  40. }
  41. }
  42. @ApiOperation(value = "查询图节点和关系", notes = "查询图节点和关系")
  43. @GetMapping(value = "/getDomainGraph")
  44. public Result getDomainGraph(@Validated GraphQuery query) {
  45. try {
  46. HashMap<String, Object> graphData = graphService.getDomainGraph(query);
  47. return success(graphData);
  48. } catch (Exception e) {
  49. log.error("查询图节点和关系异常:" + e.getMessage());
  50. return error("查询图节点和关系异常");
  51. }
  52. }
  53. @ApiOperation(value = "获取节点列表", notes = "获取节点列表")
  54. @GetMapping(value = "/getDomainNodes")
  55. public Result getDomainNodes(String domain, Integer pageIndex, Integer pageSize) {
  56. try {
  57. HashMap<String, Object> graphData = graphService.getDomainNodes(domain, pageIndex,pageSize);
  58. return success(graphData);
  59. } catch (Exception e) {
  60. log.error("获取节点列表异常:" + e.getMessage());
  61. return error("获取节点列表异常");
  62. }
  63. }
  64. @ApiOperation(value = "查询所有节点标签", notes = "查询所有的节点标签")
  65. @GetMapping(value = "/getNodesLabels")
  66. public Result getNodesLabels() {
  67. try {
  68. List<String> graphData = graphService.getNodesLabels();
  69. return success(graphData);
  70. } catch (Exception e) {
  71. log.error("查询所有节点标签异常:" + e.getMessage());
  72. return error("查询所有节点标签异常");
  73. }
  74. }
  75. @ApiOperation(value = "查询所有关系类型", notes = "查询所有关系类型")
  76. @GetMapping(value = "/getRelationshipType")
  77. public Result getRelationshipType() {
  78. try {
  79. List<String> graphData = graphService.getRelationshipType();
  80. return success(graphData);
  81. } catch (Exception e) {
  82. log.error("查询所有关系类型异常:" + e.getMessage());
  83. return error("查询所有关系类型异常");
  84. }
  85. }
  86. }

2.5.2 service

  1. package com.modules.project.service;
  2. import com.modules.common.utils.StringUtils;
  3. import com.modules.project.entity.GraphQuery;
  4. import com.modules.project.repository.GraphRepository;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Service;
  7. import java.util.HashMap;
  8. import java.util.List;
  9. /**
  10. * neo4j图库服务层
  11. *
  12. * @author li'chao
  13. *
  14. */
  15. @Service
  16. public class GraphService {
  17. @Autowired
  18. private GraphRepository graphRepository;
  19. /**
  20. * 查询图节点和关系
  21. *
  22. * @param query
  23. * @return
  24. */
  25. public HashMap<String, Object> getDomainGraph(GraphQuery query) {
  26. if(StringUtils.isNotEmpty(query.getDomain())){
  27. return graphRepository.getDomainGraph(query);
  28. }else{
  29. return graphRepository.getNodeNameGraph(query);
  30. }
  31. }
  32. /**
  33. * 获取节点列表
  34. * @param domain
  35. * @param pageIndex
  36. * @param pageSize
  37. * @return
  38. */
  39. public HashMap<String, Object> getDomainNodes(String domain, Integer pageIndex, Integer pageSize){
  40. return graphRepository.getDomainNodes(domain, pageIndex, pageSize);
  41. }
  42. /**
  43. * 查询所有节点标签
  44. * @return
  45. */
  46. public List<String> getNodesLabels(){
  47. return graphRepository.getNodesLabels();
  48. }
  49. /**
  50. * 查询所有关系类型
  51. * @return
  52. */
  53. public List<String> getRelationshipType(){
  54. return graphRepository.getRelationshipType();
  55. }
  56. }

2.5.3 repository

  1. @Override
  2. public List<String> getNodesLabels() {
  3. String cypherSql = " CALL db.labels(); ";
  4. return neo4jUtil.getNodesLabelsEntityList(cypherSql);
  5. }
  6. @Override
  7. public List<String> getRelationshipType() {
  8. String cypherSql = " CALL db.relationshipTypes(); ";
  9. return neo4jUtil.getRelationshipTypeEntityList(cypherSql);
  10. }
  11. @Override
  12. public List<String> getNodesSchema() {
  13. String cypherSql = " CALL db.schema(); ";
  14. return neo4jUtil.getRelationshipTypeEntityList(cypherSql);
  15. }
  16. /**
  17. * 查询图谱节点和关系
  18. *
  19. * @param query
  20. * @return node relationship
  21. */
  22. public HashMap<String, Object> getDomainGraph(GraphQuery query) {
  23. HashMap<String, Object> nr = new HashMap<String, Object>();
  24. try {
  25. String domain = query.getDomain();
  26. // MATCH (n:`症状`) -[r]-(m:症状) where r.name='治疗' or r.name='危险因素' return n,m
  27. if (!StringUtils.isBlank(domain)) {
  28. String cqr = "";
  29. List<String> lis = new ArrayList<String>();
  30. if (query.getRelation() != null && query.getRelation().length > 0) {
  31. for (String r : query.getRelation()) {
  32. String it = String.format("r.name='%s'", r);
  33. lis.add(it);
  34. }
  35. cqr = String.join(" or ", lis);
  36. }
  37. String cqWhere = "";
  38. if (!StringUtils.isBlank(query.getNodename()) || !StringUtils.isBlank(cqr)) {
  39. if (!StringUtils.isBlank(query.getNodename())) {
  40. if (query.getMatchtype() == 1) {
  41. cqWhere = String.format("where n.name ='%s' ", query.getNodename());
  42. } else {
  43. cqWhere = String.format("where n.name contains('%s')", query.getNodename());
  44. }
  45. }
  46. String nodeOnly = cqWhere;
  47. if (!StringUtils.isBlank(cqr)) {
  48. if (StringUtils.isBlank(cqWhere)) {
  49. cqWhere = String.format(" where ( %s )", cqr);
  50. } else {
  51. cqWhere += String.format(" and ( %s )", cqr);
  52. }
  53. }
  54. // 下边的查询查不到单个没有关系的节点,考虑要不要左箭头
  55. String nodeSql = String.format("MATCH (n:`%s`) <-[r]->(m) %s return * limit %s", domain, cqWhere,
  56. query.getPageSize());
  57. HashMap<String, Object> graphNode = neo4jUtil.getGraphNodeAndShip(nodeSql);
  58. Object node = graphNode.get("node");
  59. // 没有关系显示则显示节点
  60. if (node != null) {
  61. nr.put("node", graphNode.get("node"));
  62. nr.put("relationship", graphNode.get("relationship"));
  63. } else {
  64. String nodecql = String.format("MATCH (n:`%s`) %s RETURN distinct(n) limit %s", domain,
  65. nodeOnly, query.getPageSize());
  66. List<HashMap<String, Object>> nodeItem = neo4jUtil.getGraphNode(nodecql);
  67. nr.put("node", nodeItem);
  68. nr.put("relationship", new ArrayList<HashMap<String, Object>>());
  69. }
  70. } else {
  71. String nodeSql = String.format("MATCH (n:`%s`) %s RETURN distinct(n) limit %s", domain, cqWhere,
  72. query.getPageSize());
  73. List<HashMap<String, Object>> graphNode = neo4jUtil.getGraphNode(nodeSql);
  74. nr.put("node", graphNode);
  75. String domainSql = String.format("MATCH (n:`%s`)<-[r]-> (m) %s RETURN distinct(r) limit %s", domain,
  76. cqWhere, query.getPageSize());// m是否加领域
  77. List<HashMap<String, Object>> graphRelation = neo4jUtil.getGraphRelationShip(domainSql);
  78. nr.put("relationship", graphRelation);
  79. }
  80. }
  81. } catch (Exception e) {
  82. e.printStackTrace();
  83. }
  84. return nr;
  85. }
  86. /**
  87. * 查询图谱节点和关系(条件无节点标签)
  88. *
  89. * @param query
  90. * @return node relationship
  91. */
  92. public HashMap<String, Object> getNodeNameGraph(GraphQuery query) {
  93. HashMap<String, Object> nr = new HashMap<String, Object>();
  94. try {
  95. // MATCH (n) -[r]-(m:症状) where r.name='治疗' or r.name='危险因素' return n,m
  96. String cqr = "";
  97. List<String> lis = new ArrayList<String>();
  98. if (query.getRelation() != null && query.getRelation().length > 0) {
  99. for (String r : query.getRelation()) {
  100. String it = String.format("r.name='%s'", r);
  101. lis.add(it);
  102. }
  103. cqr = String.join(" or ", lis);
  104. }
  105. String cqWhere = "";
  106. if (!StringUtils.isBlank(query.getNodename()) || !StringUtils.isBlank(cqr)) {
  107. if (!StringUtils.isBlank(query.getNodename())) {
  108. if (query.getMatchtype() == 1) {
  109. cqWhere = String.format("where n.name ='%s' ", query.getNodename());
  110. } else {
  111. cqWhere = String.format("where n.name contains('%s')", query.getNodename());
  112. }
  113. }
  114. String nodeOnly = cqWhere;
  115. if (!StringUtils.isBlank(cqr)) {
  116. if (StringUtils.isBlank(cqWhere)) {
  117. cqWhere = String.format(" where ( %s )", cqr);
  118. } else {
  119. cqWhere += String.format(" and ( %s )", cqr);
  120. }
  121. }
  122. // 下边的查询查不到单个没有关系的节点,考虑要不要左箭头
  123. String nodeSql = String.format("MATCH (n) <-[r]->(m) %s return * limit %s", cqWhere,
  124. query.getPageSize());
  125. HashMap<String, Object> graphNode = neo4jUtil.getGraphNodeAndShip(nodeSql);
  126. Object node = graphNode.get("node");
  127. // 没有关系显示则显示节点
  128. if (node != null) {
  129. nr.put("node", graphNode.get("node"));
  130. nr.put("relationship", graphNode.get("relationship"));
  131. } else {
  132. String nodecql = String.format("MATCH (n) %s RETURN distinct(n) limit %s",
  133. nodeOnly, query.getPageSize());
  134. List<HashMap<String, Object>> nodeItem = neo4jUtil.getGraphNode(nodecql);
  135. nr.put("node", nodeItem);
  136. nr.put("relationship", new ArrayList<HashMap<String, Object>>());
  137. }
  138. } else {
  139. String nodeSql = String.format("MATCH (n) %s RETURN distinct(n) limit %s", cqWhere,
  140. query.getPageSize());
  141. List<HashMap<String, Object>> graphNode = neo4jUtil.getGraphNode(nodeSql);
  142. nr.put("node", graphNode);
  143. String domainSql = String.format("MATCH (n)<-[r]-> (m) %s RETURN distinct(r) limit %s",
  144. cqWhere, query.getPageSize());// m是否加领域
  145. List<HashMap<String, Object>> graphRelation = neo4jUtil.getGraphRelationShip(domainSql);
  146. nr.put("relationship", graphRelation);
  147. }
  148. } catch (Exception e) {
  149. e.printStackTrace();
  150. }
  151. return nr;
  152. }

2.5.4 swagger界面

三 加载CSV文件,添加图库数据

3.1 准备CSV文件

3.2 上传CSV文件至import目录下

3.3 加载CSV文件

  1. 删除所有节点
  2. MATCH (n)
  3. OPTIONAL MATCH (n)-[r]-()
  4. DELETE n,r
  5. 加载train CSV
  6. LOAD CSV WITH HEADERS FROM 'file:///train.csv' as line
  7. CREATE (:train {train_id:line.train_id,train_type:line.train_type,name:line.train_name,create_time:line.create_time})
  8. 加载task CSV
  9. LOAD CSV WITH HEADERS FROM 'file:///task.csv' as line
  10. CREATE (:task {task_id:line.task_id,train_id:line.train_id,name:line.task_name,create_time:line.create_time})
  11. 创建train和task关系
  12. LOAD CSV WITH HEADERS FROM "file:///tt.csv" AS line
  13. MATCH(a:train{train_id:line.train_id}),(b:task{task_id:line.task_id})
  14. MERGE(a) -[r:关联]->(b)
  15. 创建索引
  16. CREATE INDEX ON :train(train_id)
  17. CREATE INDEX ON :task(task_id)

3.4 图库数据

四 前端界面

前端实现技术:

cytoscape.js 官方地址:https://js.cytoscape.org/

d3.js 官方地址:D3 by Observable | The JavaScript library for bespoke data visualization

vis.js 官方地址:vis.js

普通查询

高级查询

五 源码

码云源码地址:spring-boot2-neo4j: spring-boot2-neo4j是精简的图库项目,基于Spring Boot2和Neo4j实现。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/641559
推荐阅读
相关标签
  

闽ICP备14008679号