Spring Boot2 集成 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依赖

        <!-- neo4j-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-neo4j</artifactId>
        </dependency>

        <!-- neo4j driver驱动-->
        <dependency>
            <groupId>org.neo4j.driver</groupId>
            <artifactId>neo4j-java-driver</artifactId>
            <version>1.7.5</version>
        </dependency>

完整pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.modules</groupId>
    <artifactId>spring-boot2-neo4j</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot2-neo4j</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
    </properties>
    <dependencies>

        <!-- spring boot2 核心-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!-- spring boot2 web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- devtools-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!-- test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- neo4j-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-neo4j</artifactId>
        </dependency>

        <!-- neo4j driver驱动-->
        <dependency>
            <groupId>org.neo4j.driver</groupId>
            <artifactId>neo4j-java-driver</artifactId>
            <version>1.7.5</version>
        </dependency>

        <!-- fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.58</version>
        </dependency>

        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- swagger2-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
            <exclusions>
                <exclusion>
                    <groupId>io.swagger</groupId>
                    <artifactId>swagger-annotations</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>io.swagger</groupId>
                    <artifactId>swagger-models</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- swagger2-UI-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

        <!--防止进入swagger页面报类型转换错误,排除2.9.2中的引用,手动增加1.5.21版本-->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.5.21</version>
        </dependency>

        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>1.5.21</version>
        </dependency>

    </dependencies>

    <!-- 依赖版本管理 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!-- 引入系统范围内的依赖 -->
                <configuration>
                    <includeSystemScope>true</includeSystemScope>
                </configuration>
            </plugin>
            <!--添加配置跳过测试-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

2.2 application.properties配置


server.port=8088
server.servlet.context-path=/neo4j
# 启用优雅关机
server.shutdown=graceful
# 缓冲10秒
spring.lifecycle.timeout-per-shutdown-phase=10s

# neo4j配置
spring.data.neo4j.uri= bolt://172.16.21.201:7687
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=111111

#日志配置
logging.level.com.modules.project.dao=debug

# 设置时间
spring.jackson.time-zone=GMT+8
# 全局格式化日期
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss

2.3 Neo4j 配置类

package com.modules.common.config;


import org.neo4j.driver.v1.AuthTokens;
import org.neo4j.driver.v1.Driver;
import org.neo4j.driver.v1.GraphDatabase;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * neo4j图数据库配置
 *
 * @author li'chao
 */

@Configuration
public class Neo4jConfig {
    @Value("${spring.data.neo4j.uri}")
    private String url;

    @Value("${spring.data.neo4j.username}")
    private String username;

    @Value("${spring.data.neo4j.password}")
    private String password;

    /**
     * neo4j图数据库驱动模式
     *
     * @return
     */
    @Bean
    public Driver neo4jDriver() {
        return GraphDatabase.driver(url, AuthTokens.basic(username, password));
    }
}

2.4 Neo4jUtil工具类

package com.modules.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.neo4j.driver.v1.*;
import org.neo4j.driver.v1.types.Node;
import org.neo4j.driver.v1.types.Path;
import org.neo4j.driver.v1.types.Relationship;
import org.neo4j.driver.v1.util.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.*;
import java.util.Map.Entry;

@Slf4j
@Component
public class Neo4jUtil {
	@Autowired
	private Driver neo4jDriver;

	public boolean isNeo4jOpen() {
		try (Session session = neo4jDriver.session()) {
			log.info("连接成功:" + session.isOpen());
			return session.isOpen();
		} catch (Exception e) {
			log.error("连接异常:" + e.getMessage());
			return false;
		}
	}

	public StatementResult excuteCypherSql(String cypherSql) {
		StatementResult result = null;
		try (Session session = neo4jDriver.session()) {
			log.info("cypher语句:" + cypherSql);
			result = session.run(cypherSql);
			session.close();
		} catch (Exception e) {
			throw e;
		}
		return result;
	}


	public HashMap<String, Object> getEntityMap(String cypherSql) {
		HashMap<String, Object> rss = new HashMap<String, Object>();
		try {
			StatementResult result = excuteCypherSql(cypherSql);
			if (result.hasNext()) {
				List<Record> records = result.list();
				for (Record recordItem : records) {
					for (Value value : recordItem.values()) {
						if (value.type().name().equals("NODE")) {// 结果里面只要类型为节点的值
							Node noe4jNode = value.asNode();
							Map<String, Object> map = noe4jNode.asMap();
							for (Entry<String, Object> entry : map.entrySet()) {
								String key = entry.getKey();
								if (rss.containsKey(key)) {
									String oldValue = rss.get(key).toString();
									String newValue = oldValue + "," + entry.getValue();
									rss.replace(key, newValue);
								} else {
									rss.put(key, entry.getValue());
								}
							}

						}
					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return rss;
	}

	public List<HashMap<String, Object>> getGraphNode(String cypherSql) {
		List<HashMap<String, Object>> ents = new ArrayList<HashMap<String, Object>>();
		try {
			StatementResult result = excuteCypherSql(cypherSql);
			if (result.hasNext()) {
				List<Record> records = result.list();
				for (Record recordItem : records) {
					List<Pair<String, Value>> f = recordItem.fields();
					for (Pair<String, Value> pair : f) {
						HashMap<String, Object> rss = new HashMap<String, Object>();
						String typeName = pair.value().type().name();
						if (typeName.equals("NODE")) {
							Node noe4jNode = pair.value().asNode();
							String uuid = String.valueOf(noe4jNode.id());
							Map<String, Object> map = noe4jNode.asMap();
							for (Entry<String, Object> entry : map.entrySet()) {
								String key = entry.getKey();
								rss.put(key, entry.getValue());
							}
							rss.put("uuid", uuid);
							ents.add(rss);
						}
					}

				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return ents;
	}

	public List<HashMap<String, Object>> getGraphRelationShip(String cypherSql) {
		List<HashMap<String, Object>> ents = new ArrayList<HashMap<String, Object>>();
		try {
			StatementResult result = excuteCypherSql(cypherSql);
			if (result.hasNext()) {
				List<Record> records = result.list();
				for (Record recordItem : records) {
					List<Pair<String, Value>> f = recordItem.fields();
					for (Pair<String, Value> pair : f) {
						HashMap<String, Object> rss = new HashMap<String, Object>();
						String typeName = pair.value().type().name();
						if (typeName.equals("RELATIONSHIP")) {
							Relationship rship = pair.value().asRelationship();
							String uuid = String.valueOf(rship.id());
							String sourceid = String.valueOf(rship.startNodeId());
							String targetid = String.valueOf(rship.endNodeId());
							Map<String, Object> map = rship.asMap();
							for (Entry<String, Object> entry : map.entrySet()) {
								String key = entry.getKey();
								rss.put(key, entry.getValue());
							}
							rss.put("uuid", uuid);
							rss.put("sourceid", sourceid);
							rss.put("targetid", targetid);
							ents.add(rss);
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ents;
	}
	public List<HashMap<String, Object>> getGraphItem(String cypherSql) {
		List<HashMap<String, Object>> ents = new ArrayList<HashMap<String, Object>>();
		List<String> nodeids = new ArrayList<String>();
		List<String> shipids = new ArrayList<String>();
		try {
			StatementResult result = excuteCypherSql(cypherSql);
			if (result.hasNext()) {
				List<Record> records = result.list();
				for (Record recordItem : records) {
					List<Pair<String, Value>> f = recordItem.fields();
					HashMap<String, Object> rss = new HashMap<String, Object>();
					for (Pair<String, Value> pair : f) {
						String typeName = pair.value().type().name();
						if (typeName.equals("NODE")) {
							Node noe4jNode = pair.value().asNode();
							String uuid = String.valueOf(noe4jNode.id());
							if(!nodeids.contains(uuid)) {
								Map<String, Object> map = noe4jNode.asMap();
								for (Entry<String, Object> entry : map.entrySet()) {
									String key = entry.getKey();
									rss.put(key, entry.getValue());
								}
								rss.put("uuid", uuid);
							}
						}else if (typeName.equals("RELATIONSHIP")) {
							Relationship rship = pair.value().asRelationship();
							String uuid = String.valueOf(rship.id());
							if (!shipids.contains(uuid)) {
								String sourceid = String.valueOf(rship.startNodeId());
								String targetid = String.valueOf(rship.endNodeId());
								Map<String, Object> map = rship.asMap();
								for (Entry<String, Object> entry : map.entrySet()) {
									String key = entry.getKey();
									rss.put(key, entry.getValue());
								}
								rss.put("uuid", uuid);
								rss.put("sourceid", sourceid);
								rss.put("targetid", targetid);
							}
						}else {
							rss.put(pair.key(),pair.value().toString());
						}
					}
					ents.add(rss);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ents;
	}
	/*
	 * 获取值类型的结果,如count,uuid
	 * @return 1 2 3 等数字类型
	 */
	public long getGraphValue(String cypherSql) {
		long val=0;
		try {
			StatementResult cypherResult = excuteCypherSql(cypherSql);
			if (cypherResult.hasNext()) {
				Record record = cypherResult.next();
				for (Value value : record.values()) {
					val = value.asLong();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return val;
	}

	public HashMap<String, Object> getGraphNodeAndShip(String cypherSql) {
		HashMap<String, Object> mo = new HashMap<String, Object>();
		try {
			StatementResult result = excuteCypherSql(cypherSql);
			if (result.hasNext()) {
				List<Record> records = result.list();
				List<HashMap<String, Object>> ents = new ArrayList<HashMap<String, Object>>();
				List<HashMap<String, Object>> ships = new ArrayList<HashMap<String, Object>>();
				List<String> uuids = new ArrayList<String>();
				List<String> shipids = new ArrayList<String>();
				for (Record recordItem : records) {
					List<Pair<String, Value>> f = recordItem.fields();
					for (Pair<String, Value> pair : f) {
						HashMap<String, Object> rships = new HashMap<String, Object>();
						HashMap<String, Object> rss = new HashMap<String, Object>();
						String typeName = pair.value().type().name();
						if (typeName.equals("NULL")) {
							continue;
						} else if (typeName.equals("NODE")) {
							Node noe4jNode = pair.value().asNode();
                            Map<String, Object> map = noe4jNode.asMap();
                            String uuid = String.valueOf(noe4jNode.id());
                            if (!uuids.contains(uuid)) {
                                for (Entry<String, Object> entry : map.entrySet()) {
                                    String key = entry.getKey();
                                    rss.put(key, entry.getValue());
                                }
                                rss.put("uuid", uuid);
                                uuids.add(uuid);
                            }
                            if (rss != null && !rss.isEmpty()) {
                                ents.add(rss);
                            }
						} else if (typeName.equals("RELATIONSHIP")) {
							Relationship rship = pair.value().asRelationship();
                            String uuid = String.valueOf(rship.id());
                            if (!shipids.contains(uuid)) {
                                String sourceid = String.valueOf(rship.startNodeId());
                                String targetid = String.valueOf(rship.endNodeId());
                                Map<String, Object> map = rship.asMap();
                                for (Entry<String, Object> entry : map.entrySet()) {
                                    String key = entry.getKey();
                                    rships.put(key, entry.getValue());
                                }
                                rships.put("uuid", uuid);
                                rships.put("sourceid", sourceid);
                                rships.put("targetid", targetid);
								shipids.add(uuid);
                                if (rships != null && !rships.isEmpty()) {
                                    ships.add(rships);
                                }
                            }

						} else if (typeName.equals("PATH")) {
							Path path = pair.value().asPath();
							Map<String, Object> startNodemap = path.start().asMap();
							String startNodeuuid = String.valueOf(path.start().id());
							if (!uuids.contains(startNodeuuid)) {
								rss=new HashMap<String, Object>();
								for (Entry<String, Object> entry : startNodemap.entrySet()) {
									String key = entry.getKey();
									rss.put(key, entry.getValue());
								}
								rss.put("uuid", startNodeuuid);
								uuids.add(startNodeuuid);
								if (rss != null && !rss.isEmpty()) {
									ents.add(rss);
								}
							}

							Map<String, Object> endNodemap = path.end().asMap();
							String endNodeuuid = String.valueOf(path.end().id());
							if (!uuids.contains(endNodeuuid)) {
								rss=new HashMap<String, Object>();
								for (Entry<String, Object> entry : endNodemap.entrySet()) {
									String key = entry.getKey();
									rss.put(key, entry.getValue());
								}
								rss.put("uuid", endNodeuuid);
								uuids.add(endNodeuuid);
								if (rss != null && !rss.isEmpty()) {
									ents.add(rss);
								}
							}
							Iterator<Node> allNodes = path.nodes().iterator();
							while (allNodes.hasNext()) {
								Node next = allNodes.next();
								String uuid = String.valueOf(next.id());
								if (!uuids.contains(uuid)) {
									rss=new HashMap<String, Object>();
									Map<String, Object> map = next.asMap();
									for (Entry<String, Object> entry : map.entrySet()) {
										String key = entry.getKey();
										rss.put(key, entry.getValue());
									}
									rss.put("uuid", uuid);
									uuids.add(uuid);
									if (rss != null && !rss.isEmpty()) {
										ents.add(rss);
									}
								}
							}
							Iterator<Relationship> reships = path.relationships().iterator();
							while (reships.hasNext()) {
								Relationship next = reships.next();
								String uuid = String.valueOf(next.id());
								if (!shipids.contains(uuid)) {
									rships=new HashMap<String, Object>();
									String sourceid = String.valueOf(next.startNodeId());
									String targetid = String.valueOf(next.endNodeId());
									Map<String, Object> map = next.asMap();
									for (Entry<String, Object> entry : map.entrySet()) {
										String key = entry.getKey();
										rships.put(key, entry.getValue());
									}
									rships.put("uuid", uuid);
									rships.put("sourceid", sourceid);
									rships.put("targetid", targetid);
									shipids.add(uuid);
									if (rships != null && !rships.isEmpty()) {
										ships.add(rships);
									}
								}
							}
						} else if (typeName.contains("LIST")) {
							Iterable<Value> val=pair.value().values();
                            Value next = val.iterator().next();
                            String type=next.type().name();
                            if (type.equals("RELATIONSHIP")) {
                                Relationship rship = next.asRelationship();
                                String uuid = String.valueOf(rship.id());
                                if (!shipids.contains(uuid)) {
                                    String sourceid = String.valueOf(rship.startNodeId());
                                    String targetid = String.valueOf(rship.endNodeId());
                                    Map<String, Object> map = rship.asMap();
                                    for (Entry<String, Object> entry : map.entrySet()) {
                                        String key = entry.getKey();
                                        rships.put(key, entry.getValue());
                                    }
                                    rships.put("uuid", uuid);
                                    rships.put("sourceid", sourceid);
                                    rships.put("targetid", targetid);
									shipids.add(uuid);
                                    if (rships != null && !rships.isEmpty()) {
                                        ships.add(rships);
                                    }
                                }
                            }
						} else if (typeName.contains("MAP")) {
							rss.put(pair.key(), pair.value().asMap());
						} else {
							rss.put(pair.key(), pair.value().toString());
                            if (rss != null && !rss.isEmpty()) {
                                ents.add(rss);
                            }
						}
					}
				}
				mo.put("node", ents);
				mo.put("relationship", ships);
			}
		} catch (Exception e) {
			throw new RuntimeException("执行Cypher查询异常");
		}
		return mo;
	}
	/**
	 * 匹配所有类型的节点,可以是节点,关系,数值,路径
	 * @param cypherSql
	 * @return
	 */
	public List<HashMap<String, Object>> getEntityList(String cypherSql) {
		List<HashMap<String, Object>> ents = new ArrayList<HashMap<String, Object>>();
		try {
			StatementResult result = excuteCypherSql(cypherSql);
			if (result.hasNext()) {
				List<Record> records = result.list();
				for (Record recordItem : records) {
					HashMap<String, Object> rss = new HashMap<String, Object>();
					List<Pair<String, Value>> f = recordItem.fields();
					for (Pair<String, Value> pair : f) {
						String typeName = pair.value().type().name();
						if (typeName.equals("NULL")) {
							continue;
						} else if (typeName.equals("NODE")) {
							Node noe4jNode = pair.value().asNode();
							Map<String, Object> map = noe4jNode.asMap();
							for (Entry<String, Object> entry : map.entrySet()) {
								String key = entry.getKey();
								rss.put(key, entry.getValue());
							}
						} else if (typeName.equals("RELATIONSHIP")) {
							Relationship rship = pair.value().asRelationship();
							Map<String, Object> map = rship.asMap();
							for (Entry<String, Object> entry : map.entrySet()) {
								String key = entry.getKey();
								rss.put(key, entry.getValue());
							}
						} else if (typeName.equals("PATH")) {

						} else if (typeName.contains("LIST")) {
							rss.put(pair.key(), pair.value().asList());
						} else if (typeName.contains("MAP")) {
							rss.put(pair.key(), pair.value().asMap());
						} else {
							rss.put(pair.key(), pair.value().toString());
						}
					}
					ents.add(rss);
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return ents;
	}

	public <T> List<T> getEntityItemList(String cypherSql, Class<T> type) {
		List<HashMap<String, Object>> ents = getGraphNode(cypherSql);
		List<T> model = hashMapToObject(ents, type);
		return model;
	}

	public <T> T getEntityItem(String cypherSql, Class<T> type) {
		HashMap<String, Object> rss = new HashMap<String, Object>();
		try {
			StatementResult result = excuteCypherSql(cypherSql);
			if (result.hasNext()) {
				Record record = result.next();
				for (Value value : record.values()) {
					if (value.type().name().equals("NODE")) {// 结果里面只要类型为节点的值
						Node noe4jNode = value.asNode();
						Map<String, Object> map = noe4jNode.asMap();
						for (Entry<String, Object> entry : map.entrySet()) {
							String key = entry.getKey();
							if (rss.containsKey(key)) {
								String oldValue = rss.get(key).toString();
								String newValue = oldValue + "," + entry.getValue();
								rss.replace(key, newValue);
							} else {
								rss.put(key, entry.getValue());
							}
						}

					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		T model = hashMapToObjectItem(rss, type);
		return model;
	}

	public HashMap<String, Object> getEntity(String cypherSql) {
		HashMap<String, Object> rss = new HashMap<String, Object>();
		try {
			StatementResult result = excuteCypherSql(cypherSql);
			if (result.hasNext()) {
				Record record = result.next();
				for (Value value : record.values()) {
					String t = value.type().name();
					if (value.type().name().equals("NODE")) {// 结果里面只要类型为节点的值
						Node noe4jNode = value.asNode();
						Map<String, Object> map = noe4jNode.asMap();
						for (Entry<String, Object> entry : map.entrySet()) {
							String key = entry.getKey();
							if (rss.containsKey(key)) {
								String oldValue = rss.get(key).toString();
								String newValue = oldValue + "," + entry.getValue();
								rss.replace(key, newValue);
							} else {
								rss.put(key, entry.getValue());
							}
						}

					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return rss;
	}

	public Integer executeScalar(String cypherSql) {
		Integer count = 0;
		try {
			StatementResult result = excuteCypherSql(cypherSql);
			if (result.hasNext()) {
				Record record = result.next();
				for (Value value : record.values()) {
					String t = value.type().name();
					if (t.equals("INTEGER")) {
						count = Integer.valueOf(value.toString());
						break;
					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return count;
	}

	public HashMap<String, Object> getRelevantEntity(String cypherSql) {
		HashMap<String, Object> rss = new HashMap<String, Object>();
		try {
			StatementResult resultNode = excuteCypherSql(cypherSql);
			if (resultNode.hasNext()) {
				List<Record> records = resultNode.list();
				for (Record recordItem : records) {
					Map<String, Object> r = recordItem.asMap();
					String key = r.get("key").toString();
					if (rss.containsKey(key)) {
						String oldValue = rss.get(key).toString();
						String newValue = oldValue + "," + r.get("value");
						rss.replace(key, newValue);
					} else {
						rss.put(key, r.get("value"));
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rss;
	}



	public String getFilterPropertiesJson(String jsonStr) {
		String propertiesString = jsonStr.replaceAll("\"(\\w+)\"(\\s*:\\s*)", "$1$2"); // 去掉key的引号
		return propertiesString;
	}

	public <T>String getkeyvalCyphersql(T obj) {
		 Map<String, Object> map = new HashMap<String, Object>();
		 List<String> sqlList=new ArrayList<String>();
	        // 得到类对象
	        Class userCla = obj.getClass();
	        /* 得到类中的所有属性集合 */
	        Field[] fs = userCla.getDeclaredFields();
	        for (int i = 0; i < fs.length; i++) {
	            Field f = fs[i];
	            Class type = f.getType();

	            f.setAccessible(true); // 设置些属性是可以访问的
	            Object val = new Object();
	            try {
	                val = f.get(obj);
	                if(val==null) {
	                	val="";
	                }
	                String sql="";
	                String key=f.getName();
	                log.info("key:"+key+"type:"+type);
	                if ( val instanceof   Integer ){
	                	// 得到此属性的值
		                map.put(key, val);// 设置键值
		                sql="n."+key+"="+val;
	    			}
	                else if ( val instanceof   String[] ){
	    				//如果为true则强转成String数组
	    				String [] arr = ( String[] ) val ;
	    				String v="";
	    				for ( int j = 0 ; j < arr.length ; j++ ){
	    					arr[j]="'"+ arr[j]+"'";
	    				}
	    				v=String.join(",", arr);
	    				sql="n."+key+"=["+val+"]";
	    			}
	                else if (val instanceof List){
	    				//如果为true则强转成String数组
	                	List<String> arr = ( ArrayList<String> ) val ;
	                	List<String> aa=new ArrayList<String>();
	    				String v="";
	    				for (String s : arr) {
	    					s="'"+ s+"'";
	    					aa.add(s);
						}
	    				v=String.join(",", aa);
	    				sql="n."+key+"=["+v+"]";
	    			}
	                else {
	                	// 得到此属性的值
		                map.put(key, val);// 设置键值
		                sql="n."+key+"='"+val+"'";
	                }

	                sqlList.add(sql);
	            } catch (IllegalArgumentException e) {
	                e.printStackTrace();
	            } catch (IllegalAccessException e) {
	                e.printStackTrace();
	            }
	        }
	        String finasql=String.join(",",sqlList);
	        log.info("单个对象的所有键值==反射==" + map.toString());
		return finasql;
	}
	public <T> List<T> hashMapToObject(List<HashMap<String, Object>> maps, Class<T> type) {
		try {
			List<T> list = new ArrayList<T>();
			for (HashMap<String, Object> r : maps) {
				T t = type.newInstance();
				Iterator iter = r.entrySet().iterator();// 该方法获取列名.获取一系列字段名称.例如name,age...
				while (iter.hasNext()) {
					Entry entry = (Entry) iter.next();// 把hashmap转成Iterator再迭代到entry
					String key = entry.getKey().toString(); // 从iterator遍历获取key
					Object value = entry.getValue(); // 从hashmap遍历获取value
					if("serialVersionUID".toLowerCase().equals(key.toLowerCase()))continue;
					Field field = type.getDeclaredField(key);// 获取field对象
					if (field != null) {
						field.setAccessible(true);
						if (field.getType() == int.class || field.getType() == Integer.class) {
							if (value==null||StringUtils.isBlank(value.toString())) {
								field.set(t, 0);// 设置值
							} else {
								field.set(t, Integer.parseInt(value.toString()));// 设置值
							}
						}
						 else if (field.getType() == long.class||field.getType() == Long.class ) {
								if (value==null||StringUtils.isBlank(value.toString())) {
									field.set(t, 0);// 设置值
								} else {
									field.set(t, Long.parseLong(value.toString()));// 设置值
								}

						}
						 else {
							field.set(t, value);// 设置值
						}
					}

				}
				list.add(t);
			}

			return list;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public <T> T hashMapToObjectItem(HashMap<String, Object> map, Class<T> type) {
		try {
			T t = type.newInstance();
			Iterator iter = map.entrySet().iterator();
			while (iter.hasNext()) {
				Entry entry = (Entry) iter.next();// 把hashmap转成Iterator再迭代到entry
				String key = entry.getKey().toString(); // 从iterator遍历获取key
				Object value = entry.getValue(); // 从hashmap遍历获取value
				if("serialVersionUID".toLowerCase().equals(key.toLowerCase()))continue;
				Field field = type.getDeclaredField(key);// 获取field对象
				if (field != null) {
					field.setAccessible(true);
					if (field.getType() == int.class || field.getType() == Integer.class) {
						if (value==null||StringUtils.isBlank(value.toString())) {
							field.set(t, 0);// 设置值
						} else {
							field.set(t, Integer.parseInt(value.toString()));// 设置值
						}
					}
					 else if (field.getType() == long.class||field.getType() == Long.class ) {
							if (value==null||StringUtils.isBlank(value.toString())) {
								field.set(t, 0);// 设置值
							} else {
								field.set(t, Long.parseLong(value.toString()));// 设置值
							}

					}
					 else {
						field.set(t, value);// 设置值
					}
				}

			}
			return t;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public List<String> getNodesLabelsEntityList(String cypherSql) {
		List<String> rss = new ArrayList<>();
		try {
			StatementResult resultNode = excuteCypherSql(cypherSql);
			if (resultNode.hasNext()) {
				List<Record> records = resultNode.list();
				for (Record recordItem : records) {
					Map<String, Object> r = recordItem.asMap();
					rss.add(r.get("label").toString());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rss;
	}

	public List<String> getRelationshipTypeEntityList(String cypherSql) {
		List<String> rss = new ArrayList<>();
		try {
			StatementResult resultNode = excuteCypherSql(cypherSql);
			if (resultNode.hasNext()) {
				List<Record> records = resultNode.list();
				for (Record recordItem : records) {
					Map<String, Object> r = recordItem.asMap();
					rss.add(r.get("relationshipType").toString());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rss;
	}
}

2.5 实现图库数据查询功能

2.5.1 controller

package com.modules.project.controller;

import com.modules.common.utils.Neo4jUtil;
import com.modules.common.web.BaseController;
import com.modules.common.web.Result;
import com.modules.project.entity.GraphQuery;
import com.modules.project.service.GraphService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * neo4j图数据管理
 *
 * @author li'chao
 */

@Api(tags = "neo4j图数据管理")
@Slf4j
@RestController
@RequestMapping("/graph")
public class GraphController extends BaseController {

    @Autowired
    private Neo4jUtil neo4jUtil;

    @Autowired
    private GraphService graphService;

    @ApiOperation(value = "执行Cypher查询", notes = "执行Cypher查询")
    @GetMapping(value = "/getCypherResult")
    public Result getCypherResult(String cypher) {
        try {
            HashMap<String, Object> graphData = neo4jUtil.getGraphNodeAndShip(cypher);
            return success(graphData);
        } catch (Exception e) {
            log.error("执行Cypher查询异常:" + e.getMessage());
           return error("执行Cypher查询异常");
        }
    }

    @ApiOperation(value = "查询图节点和关系", notes = "查询图节点和关系")
    @GetMapping(value = "/getDomainGraph")
    public Result getDomainGraph(@Validated GraphQuery query) {
        try {
            HashMap<String, Object> graphData = graphService.getDomainGraph(query);
            return success(graphData);
        } catch (Exception e) {
            log.error("查询图节点和关系异常:" + e.getMessage());
           return error("查询图节点和关系异常");
        }
    }

    @ApiOperation(value = "获取节点列表", notes = "获取节点列表")
    @GetMapping(value = "/getDomainNodes")
    public Result getDomainNodes(String domain, Integer pageIndex, Integer pageSize) {
        try {
            HashMap<String, Object> graphData = graphService.getDomainNodes(domain, pageIndex,pageSize);
            return success(graphData);
        } catch (Exception e) {
            log.error("获取节点列表异常:" + e.getMessage());
            return error("获取节点列表异常");
        }
    }

    @ApiOperation(value = "查询所有节点标签", notes = "查询所有的节点标签")
    @GetMapping(value = "/getNodesLabels")
    public Result getNodesLabels() {
        try {
            List<String> graphData = graphService.getNodesLabels();
            return success(graphData);
        } catch (Exception e) {
            log.error("查询所有节点标签异常:" + e.getMessage());
            return error("查询所有节点标签异常");
        }
    }

    @ApiOperation(value = "查询所有关系类型", notes = "查询所有关系类型")
    @GetMapping(value = "/getRelationshipType")
    public Result getRelationshipType() {
        try {
            List<String> graphData = graphService.getRelationshipType();
            return success(graphData);
        } catch (Exception e) {
            log.error("查询所有关系类型异常:" + e.getMessage());
            return error("查询所有关系类型异常");
        }
    }
}

2.5.2 service

package com.modules.project.service;

import com.modules.common.utils.StringUtils;
import com.modules.project.entity.GraphQuery;
import com.modules.project.repository.GraphRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * neo4j图库服务层
 *
 * @author li'chao
 *
 */

@Service
public class GraphService {

    @Autowired
    private GraphRepository graphRepository;

    /**
     * 查询图节点和关系
     *
     * @param query
     * @return
     */
    public HashMap<String, Object> getDomainGraph(GraphQuery query) {
        if(StringUtils.isNotEmpty(query.getDomain())){
            return graphRepository.getDomainGraph(query);
        }else{
            return graphRepository.getNodeNameGraph(query);
        }
    }

    /**
     * 获取节点列表
     * @param domain
     * @param pageIndex
     * @param pageSize
     * @return
     */
    public HashMap<String, Object> getDomainNodes(String domain, Integer pageIndex, Integer pageSize){
        return graphRepository.getDomainNodes(domain, pageIndex, pageSize);
    }

    /**
     * 查询所有节点标签
     * @return
     */
    public List<String> getNodesLabels(){
        return graphRepository.getNodesLabels();
    }

    /**
     * 查询所有关系类型
     * @return
     */
    public List<String> getRelationshipType(){
        return graphRepository.getRelationshipType();
    }
}

2.5.3 repository

	@Override
	public List<String> getNodesLabels() {
		String cypherSql = " CALL db.labels(); ";
		return neo4jUtil.getNodesLabelsEntityList(cypherSql);
	}

	@Override
	public List<String> getRelationshipType() {
		String cypherSql = " CALL db.relationshipTypes(); ";
		return neo4jUtil.getRelationshipTypeEntityList(cypherSql);
	}

	@Override
	public List<String> getNodesSchema() {
		String cypherSql = " CALL db.schema(); ";
		return neo4jUtil.getRelationshipTypeEntityList(cypherSql);
	}


	/**
	 * 查询图谱节点和关系
	 *
	 * @param query
	 * @return node relationship
	 */
	public HashMap<String, Object> getDomainGraph(GraphQuery query) {
		HashMap<String, Object> nr = new HashMap<String, Object>();
		try {
			String domain = query.getDomain();
			// MATCH (n:`症状`) -[r]-(m:症状) where r.name='治疗' or r.name='危险因素' return n,m
			if (!StringUtils.isBlank(domain)) {
				String cqr = "";
				List<String> lis = new ArrayList<String>();
				if (query.getRelation() != null && query.getRelation().length > 0) {
					for (String r : query.getRelation()) {
						String it = String.format("r.name='%s'", r);
						lis.add(it);
					}
					cqr = String.join(" or ", lis);
				}
				String cqWhere = "";
				if (!StringUtils.isBlank(query.getNodename()) || !StringUtils.isBlank(cqr)) {

					if (!StringUtils.isBlank(query.getNodename())) {
						if (query.getMatchtype() == 1) {
							cqWhere = String.format("where n.name ='%s' ", query.getNodename());

						} else {
							cqWhere = String.format("where n.name contains('%s')", query.getNodename());
						}
					}
					String nodeOnly = cqWhere;
					if (!StringUtils.isBlank(cqr)) {
						if (StringUtils.isBlank(cqWhere)) {
							cqWhere = String.format(" where ( %s )", cqr);

						} else {
							cqWhere += String.format(" and ( %s )", cqr);
						}

					}
					// 下边的查询查不到单个没有关系的节点,考虑要不要左箭头
					String nodeSql = String.format("MATCH (n:`%s`) <-[r]->(m) %s return * limit %s", domain, cqWhere,
							query.getPageSize());
					HashMap<String, Object> graphNode = neo4jUtil.getGraphNodeAndShip(nodeSql);
					Object node = graphNode.get("node");
					// 没有关系显示则显示节点
					if (node != null) {
						nr.put("node", graphNode.get("node"));
						nr.put("relationship", graphNode.get("relationship"));
					} else {
						String nodecql = String.format("MATCH (n:`%s`) %s RETURN distinct(n) limit %s", domain,
								nodeOnly, query.getPageSize());
						List<HashMap<String, Object>> nodeItem = neo4jUtil.getGraphNode(nodecql);
						nr.put("node", nodeItem);
						nr.put("relationship", new ArrayList<HashMap<String, Object>>());
					}
				} else {
					String nodeSql = String.format("MATCH (n:`%s`) %s RETURN distinct(n) limit %s", domain, cqWhere,
							query.getPageSize());
					List<HashMap<String, Object>> graphNode = neo4jUtil.getGraphNode(nodeSql);
					nr.put("node", graphNode);
					String domainSql = String.format("MATCH (n:`%s`)<-[r]-> (m) %s RETURN distinct(r) limit %s", domain,
							cqWhere, query.getPageSize());// m是否加领域
					List<HashMap<String, Object>> graphRelation = neo4jUtil.getGraphRelationShip(domainSql);
					nr.put("relationship", graphRelation);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return nr;
	}

	/**
	 * 查询图谱节点和关系(条件无节点标签)
	 *
	 * @param query
	 * @return node relationship
	 */
	public HashMap<String, Object> getNodeNameGraph(GraphQuery query) {
		HashMap<String, Object> nr = new HashMap<String, Object>();
		try {
			// MATCH (n) -[r]-(m:症状) where r.name='治疗' or r.name='危险因素' return n,m
			String cqr = "";
			List<String> lis = new ArrayList<String>();
			if (query.getRelation() != null && query.getRelation().length > 0) {
				for (String r : query.getRelation()) {
					String it = String.format("r.name='%s'", r);
					lis.add(it);
				}
				cqr = String.join(" or ", lis);
			}
			String cqWhere = "";
			if (!StringUtils.isBlank(query.getNodename()) || !StringUtils.isBlank(cqr)) {

				if (!StringUtils.isBlank(query.getNodename())) {
					if (query.getMatchtype() == 1) {
						cqWhere = String.format("where n.name ='%s' ", query.getNodename());

					} else {
						cqWhere = String.format("where n.name contains('%s')", query.getNodename());
					}
				}
				String nodeOnly = cqWhere;
				if (!StringUtils.isBlank(cqr)) {
					if (StringUtils.isBlank(cqWhere)) {
						cqWhere = String.format(" where ( %s )", cqr);

					} else {
						cqWhere += String.format(" and ( %s )", cqr);
					}
				}
				// 下边的查询查不到单个没有关系的节点,考虑要不要左箭头
				String nodeSql = String.format("MATCH (n) <-[r]->(m) %s return * limit %s", cqWhere,
						query.getPageSize());
				HashMap<String, Object> graphNode = neo4jUtil.getGraphNodeAndShip(nodeSql);
				Object node = graphNode.get("node");
				// 没有关系显示则显示节点
				if (node != null) {
					nr.put("node", graphNode.get("node"));
					nr.put("relationship", graphNode.get("relationship"));
				} else {
					String nodecql = String.format("MATCH (n) %s RETURN distinct(n) limit %s",
							nodeOnly, query.getPageSize());
					List<HashMap<String, Object>> nodeItem = neo4jUtil.getGraphNode(nodecql);
					nr.put("node", nodeItem);
					nr.put("relationship", new ArrayList<HashMap<String, Object>>());
				}
			} else {
				String nodeSql = String.format("MATCH (n) %s RETURN distinct(n) limit %s", cqWhere,
						query.getPageSize());
				List<HashMap<String, Object>> graphNode = neo4jUtil.getGraphNode(nodeSql);
				nr.put("node", graphNode);
				String domainSql = String.format("MATCH (n)<-[r]-> (m) %s RETURN distinct(r) limit %s",
						cqWhere, query.getPageSize());// m是否加领域
				List<HashMap<String, Object>> graphRelation = neo4jUtil.getGraphRelationShip(domainSql);
				nr.put("relationship", graphRelation);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return nr;
	}

2.5.4 swagger界面

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

3.1 准备CSV文件

3.2 上传CSV文件至import目录下

3.3 加载CSV文件

删除所有节点
MATCH (n)
OPTIONAL MATCH (n)-[r]-()
DELETE n,r

加载train CSV
LOAD CSV WITH HEADERS FROM 'file:///train.csv' as line
CREATE (:train {train_id:line.train_id,train_type:line.train_type,name:line.train_name,create_time:line.create_time})

加载task CSV
LOAD CSV WITH HEADERS FROM 'file:///task.csv' as line
CREATE (:task {task_id:line.task_id,train_id:line.train_id,name:line.task_name,create_time:line.create_time})

创建train和task关系
LOAD CSV WITH HEADERS FROM "file:///tt.csv" AS line
MATCH(a:train{train_id:line.train_id}),(b:task{task_id:line.task_id})
MERGE(a) -[r:关联]->(b)

创建索引
CREATE INDEX ON :train(train_id)
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实现。

  • 9
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 33
    评论
【资源说明】 1、基于springboot+知识图谱的数字图书馆系统源码.zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 4、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip 基于springboot+知识图谱的数字图书馆系统源码.zip
### 回答1: Spring Boot Neo4j 是一个基于 Spring Boot 框架的 Neo4j 图数据库应用程序开发框架。它提供了一系列的 API 和工具,帮助开发者快速构建和管理知识图谱应用程序。通过 Spring Boot Neo4j,开发者可以轻松地创建和管理节点、关系和属性,实现知识图谱的可视化展示和数据分析。同时,Spring Boot Neo4j 还支持多种数据存储和查询方式,包括 Cypher 查询语言和 Java API 等。它是构建知识图谱应用程序的一个强大工具。 ### 回答2: Spring Boot Neo4j知识图谱是一种基于Spring Boot框架和Neo4j图形数据库的知识图谱应用程序开发方案。知识图谱是一种基于图形结构的数据存储和查询方法,能够以更自然的方式对数据进行建模和操作。它不仅能够支持复杂的数据查询和处理任务,还能够帮助企业构建更智能的系统和服务。 Spring Boot Neo4j知识图谱的主要特点包括: 1. 灵活的数据建模:Neo4j是一个基于节点(Node)和关系(Relationship)的图形数据库,通过这种方式可以更加自然地建模和组织数据。使用Spring Boot Neo4j,可以利用Neo4j的节点和关系来建立知识图谱,并且灵活地处理各种实体和关系之间的复杂关系。 2. 快速的数据查询:Neo4j能够在复杂的关系网络中快速地定位和查询数据,这种查询方式非常适用于需要快速搜索特定数据的应用。使用Spring Boot Neo4j,用户可以轻松地编写Cypher查询语句,从而快速地查询知识图谱中的数据。 3. 高效的数据处理:知识图谱处理任务通常需要处理大量的数据,这对于传统的数据库系统来说可能是一种挑战。然而,Neo4j采用了一种内存映射技术,可以非常高效地处理大量的数据。同时,Spring Boot提供了丰富的扩展机制,使得用户可以自由地扩展系统的功能和性能。 4. 简便的集成和部署:Spring Boot是一种非常便捷的应用程序开发框架,它可以充分利用Java的生态系统,并且提供了很多常用的组件和工具。Spring Boot Neo4j利用了Spring Boot的这些优点,可以快速地构建、测试和部署知识图谱应用程序。 总之,Spring Boot Neo4j知识图谱是一种非常实用的应用程序开发方案,它可以帮助企业构建更智能、更强大的系统和服务,应用于知识管理、推荐系统、社交网络、金融和医疗等领域。 ### 回答3: Spring Boot是一个基于Spring框架的快速开发应用程序的工具。它允许开发人员可以更快速、更容易地构建、部署和运行应用程序。而Neo4j是一种开源的图形数据库,可以存储和管理网络、社交媒体、金融和推荐数据。它适用于需要处理大量连接数据的应用程序场景。 知识图谱是一种图形数据库,并提供了一个完整的知识管理和数据挖掘平台,它通过图形、搜索、推理以及其他技术,对多源异构的数据进行建模与智能分析。将Spring BootNeo4j结合使用,可以实现知识图谱的构建和应用。 在Spring Boot中使用Neo4j,需要引入Spring Data Neo4j插件。Spring Data Neo4j提供了一些注解和API操作来简化图形数据库的使用,并与Spring Boot集成得非常紧密。可以通过注解来定义图形数据库中的节点和关系,在查询时可以使用一些简单的方法,如通过名称或其他属性过滤节点,或者通过指定节点之间的关系进行遍历。 通过使用Spring BootNeo4j,开发人员可以更轻松地管理和查询图形数据库,适应更复杂的数据模型和图形查询,并利用Neo4j的图形算法来实现更深入的数据分析。此外,这种方法还可以最小化与数据库平台的交互,提高应用程序的性能和可扩展性。最终将构建出强大的知识图谱应用程序,帮助我们更好地了解和管理数据。
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十点摆码

有用你就打赏一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值