springboot集成neo4j搭建知识图谱后端项目(一)

embedded/2025/3/13 19:50:02/

springboot集成neo4j搭建知识图谱后端项目(一)

  • 1.概述
  • 2.安装neo4j
  • 3.项目搭建
    • 3.1.引入pom依赖
    • 3.2.添加application.yml配置
    • 3.3.添加Neo4jConfig.java配置
    • 3.4.添加Neo4jService接口
    • 3.5.添加Neo4jServiceImpl实现类
    • 3.7.调用
  • 4.总结

1.概述

        getee项目开源地址:springboot集成neo4j搭建知识图谱后端项目
        本文主要实现springboot集成neo4j,实现动态创建neo4j节点以及关系。数据同时存储在postgresql数据库以及neo4j

neo4j_4">2.安装neo4j

        使用docker-compose安装neo4j,可以参考这篇文章docker-compose安装neo4j

3.项目搭建

        本项目springboot版本为2.7.18。

3.1.引入pom依赖

        <!-- Spring Boot Data Neo4j 依赖,用于集成 Neo4j 数据库 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-neo4j</artifactId><version>2.7.18</version></dependency><!-- Neo4j Driver --><dependency><groupId>org.neo4j.driver</groupId><artifactId>neo4j-java-driver</artifactId><version>4.4.12</version></dependency>

3.2.添加application.yml配置

spring:# Neo4j数据源neo4j:uri: bolt://192.168.80.196:7687authentication:username: neo4jpassword: 123456# postgresql数据源datasource:driver-class-name: org.postgresql.Driverurl: jdbc:postgresql://${ENV_DB_IP:127.0.0.1}:${ENV_DB_PORT:5432}/${ENV_DB_NAME:test}?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true&stringtype=unspecifiedusername: postgrespassword: postgres

3.3.添加Neo4jConfig.java配置

package com.example.graph.config;import lombok.Data;
import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.Driver;
import org.neo4j.driver.GraphDatabase;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** neo4j连接配置*/
@Configuration
@ConfigurationProperties(prefix = "spring.neo4j")
@Data
public class Neo4jConfig {private String uri;private Authentication authentication;// 创建 Neo4j Driver@Beanpublic Driver createDriver() {return GraphDatabase.driver(uri, AuthTokens.basic(authentication.getUsername(), authentication.getPassword()));}// 嵌套类,用于映射 authentication 配置@Datapublic static class Authentication {private String username;private String password;}}

3.4.添加Neo4jService接口

package com.example.graph.service;import com.example.graph.entity.Entity;
import com.example.graph.entity.EntityAttribute;
import com.example.graph.vo.NodeRelationVO;
import org.neo4j.driver.Record;
import org.neo4j.driver.types.Node;import java.util.List;public interface Neo4jService {/*** 新增节点** @param entity*/<T> void createNode(Entity entity);/*** 修改节点** @param id* @param nodeLabel* @param attributeList*/<T> void updateNode(String id, String nodeLabel, List<EntityAttribute> attributeList);/*** 删除节点** @param id id* @param nodeLabel 节点类型*/void deleteNodeById(String id, String nodeLabel);Node findNodeById(String nodeLabel, String id);/*** 用自定义id属性来创建关系** @param fromNode* @param toNode* @param relationship*/void createRelationship(Node fromNode, Node toNode, String relationship);List<NodeRelationVO> selectNodeRelationByPath(String nodeId, String nodeLabel, Integer path);void deleteAll();}

3.5.添加Neo4jServiceImpl实现类

package com.example.graph.service.impl;import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.BeanUtils;
import com.example.graph.entity.Entity;
import com.example.graph.entity.EntityAttribute;
import com.example.graph.service.Neo4jService;
import com.example.graph.vo.NodeRelationVO;
import com.example.graph.vo.NodeVO;
import com.example.graph.vo.RelationShipVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.neo4j.driver.Driver;
import org.neo4j.driver.Record;
import org.neo4j.driver.Result;
import org.neo4j.driver.Session;
import org.neo4j.driver.types.Node;
import org.neo4j.driver.types.Relationship;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.List;
import java.util.Map;@Slf4j
@Service
@RequiredArgsConstructor
public class Neo4jServiceImpl implements Neo4jService {private final Driver neo4jDriver;@Overridepublic <T> void createNode(Entity entity) {try (Session session = neo4jDriver.session()) {StringBuilder cypherQuery = new StringBuilder("CREATE (n:" + entity.getLabel() + " {");cypherQuery.append("id: \"").append(entity.getId()).append("\"").append(", ");entity.getAttributeList().stream().forEach(attribute -> {cypherQuery.append(attribute.getLabel()).append(": \"").append(attribute.getValue()).append("\"").append(", ");});cypherQuery.delete(cypherQuery.length() - 2, cypherQuery.length());cypherQuery.append("})");session.run(cypherQuery.toString());log.info("createNode执行cql={}", cypherQuery);}}@Overridepublic <T> void updateNode(String id, String nodeLabel, List<EntityAttribute> attributeList) {try (Session session = neo4jDriver.session()) {StringBuilder cypherQuery = new StringBuilder("MATCH (n:" + nodeLabel + " {id: \"" + id + "\"}) SET ");attributeList.stream().forEach(attribute -> {cypherQuery.append("n.").append(attribute.getLabel()).append(" = \"").append(attribute.getValue()).append("\", ");});cypherQuery.delete(cypherQuery.length() - 2, cypherQuery.length());cypherQuery.append(" RETURN n");session.run(cypherQuery.toString());log.info("updateNode执行cql={}", cypherQuery);}}@Overridepublic void deleteNodeById(String id, String nodeLabel) {try (Session session = neo4jDriver.session()) {String cql = StrUtil.format("MATCH (n:{}) WHERE n.id = '{}' DETACH DELETE n", nodeLabel, id);session.run(cql);log.info("deleteNodeById执行cql={}", cql);}}@Overridepublic Node findNodeById(String nodeLabel, String id) {try (Session session = neo4jDriver.session()) {String cql = StrUtil.format("MATCH (n:{} {id: '{}' }) RETURN n", nodeLabel, id);Result result = session.run(cql);while (result.hasNext()) {Record record = result.next();Node node = record.get("n").asNode();return node;}return null;}}@Overridepublic void createRelationship(Node fromNode, Node toNode, String relationship) {String fromNodeLabel = fromNode.labels().iterator().next();Map<String, Object> fromNodeMap = fromNode.asMap();String toNodeLabel = toNode.labels().iterator().next();Map<String, Object> toNodeMap = toNode.asMap();try (Session session = neo4jDriver.session()) {String cypherQuery = "MATCH (a:" + fromNodeLabel + " {id: \"" + fromNodeMap.get("id") + "\"}), " +"(b:" + toNodeLabel + " {id: \"" + toNodeMap.get("id") + "\"}) " +"CREATE (a)-[r:" + relationship + "]->(b)";session.run(cypherQuery);log.info("createRelationship执行cql={}", cypherQuery);}}/*** 查询与a节点存在关系、且距离为1的所有节点* MATCH (a:student {id: '7'})-[r]-(b) RETURN a, r, b;** @param nodeId    节点id* @param nodeLabel 节点标签*/@Overridepublic List<NodeRelationVO> selectNodeRelationByPath(String nodeId, String nodeLabel, Integer path) {try (Session session = neo4jDriver.session()) {String cql = StrUtil.format("MATCH (a:{} {id: '{}'})-[r]-(b) RETURN a, r, b", nodeLabel, nodeId);if (path > 1) {cql = StrUtil.format("MATCH (a:{} {id: '{}'})-[r*1..{}]-(b) RETURN a, r, b", nodeLabel, nodeId, path);}Result result = session.run(cql);List<NodeRelationVO> list = new ArrayList<>();while (result.hasNext()) {Record record = result.next();Node nodeA = record.get("a").asNode();Relationship relationship = record.get("r").asRelationship();Node nodeB = record.get("b").asNode();NodeRelationVO nodeRelationVO = new NodeRelationVO();NodeVO fromNodeVO = new NodeVO();fromNodeVO.setNodeId(nodeA.id());fromNodeVO.setNodeLabel(nodeA.labels().iterator().next());fromNodeVO.setNodeProperties(nodeA.asMap());RelationShipVO relationShipVO = new RelationShipVO();relationShipVO.setRelationType(relationship.type());relationShipVO.setRelationProperties(relationship.asMap());relationShipVO.setStartNodeId(relationship.startNodeId());relationShipVO.setEndNodeId(relationship.endNodeId());NodeVO toNodeVO = new NodeVO();toNodeVO.setNodeId(nodeB.id());toNodeVO.setNodeLabel(nodeB.labels().iterator().next());toNodeVO.setNodeProperties(nodeB.asMap());nodeRelationVO.setNodeA(fromNodeVO);nodeRelationVO.setRelationShipVO(relationShipVO);nodeRelationVO.setNodeB(toNodeVO);list.add(nodeRelationVO);}log.info("selectNodeRelation执行cql={}", cql);return list;}}@Overridepublic void deleteAll() {try (Session session = neo4jDriver.session()) {String cql = StrUtil.format("MATCH (n) DETACH DELETE n");session.run(cql);log.info("deleteAll执行cql={}", cql);}}}

3.7.调用

在其他类注入,然后调用方法即可

	@Autowiredprivate Neo4jServiceImpl neo4jService;

4.总结

本文主要是采用拼接cql的方式,来实现对neo4j的一些基础操作。
存在问题:可能会存在cql注入风险,后续需要优化。


http://www.ppmy.cn/embedded/172335.html

相关文章

深入解析 JVM —— 从基础概念到实战调优的全链路学习指南

文章目录 一、为什么要学习 JVM&#xff1f;1. 面试必备与技能提升2. 性能优化与问题诊断3. 编写高质量代码 二、JVM 基础概念与体系结构1. JVM 简介2. JDK、JRE 与 JVM 三、JVM 内存模型1. 线程私有区2. 线程共享区 四、类加载机制与双亲委派1. 类加载过程2. 双亲委派模型3. 动…

CGI程序处理每一帧VDEC视频数据并输出到HTML页面

VDEC视频流刷新到网页的流程框图 上图是HTML页面显示VDEC解码数据的过程&#xff0c;RV1126后台程序把每一帧的VDEC解码数据发到shareMemory_Video共享内存里面。CGI程序从共享内存里面获取每一帧VDEC数据&#xff0c;这里需要注意的是获取共享内存数据的时候要用到P/V操作保证…

Java程序开发之Spring Boot快速入门:5分钟搭建RESTful API

一、Spring Boot核心优势速览 1. 传统Spring vs Spring Boot对比 特性SpringSpring Boot配置方式XML/Java Config自动配置内嵌服务器需手动部署Tomcat/Jetty内置依赖管理手动指定Starter POMs监控需集成第三方Actuator内置启动速度较慢秒级启动 二、5分钟极速开发实战 1. 创…

Android电量与流量优化

Android电量与流量优化 一、电量优化基础 1.1 电量消耗原理 Android设备的电量消耗主要来源于以下几个方面: 屏幕显示:屏幕是耗电量最大的硬件之一,尤其是高亮度和高刷新率的屏幕。CPU处理:CPU执行计算任务时会消耗大量电量,尤其是高负载运算。网络通信:移动数据、Wi-…

大语言模型(LLM)的微调与应用

一、微调与应用的核心区别 目标差异 微调&#xff08;Fine-tuning&#xff09;&#xff1a;针对预训练模型进行参数调整&#xff0c;使其适应特定任务或领域&#xff08;如医疗问答、法律文本分析&#xff09;。需通过有监督微调&#xff08;SFT&#xff09;或低秩适配&#xf…

Python----计算机视觉处理(Opencv:自适应二值化,取均值,加权求和(高斯定理))

一、自适应二值化 与二值化算法相比&#xff0c;自适应二值化更加适合用在明暗分布不均的图片&#xff0c;因为图片的明暗不均&#xff0c;导致图片 上的每一小部分都要使用不同的阈值进行二值化处理&#xff0c;这时候传统的二值化算法就无法满足我们的需求 了&#xff0c;于是…

微信小程序审核失败,你的小程序涉及提供播放、观看等服务,请补充选择:文娱-其他视频类目 解决

之前审核的都没有什么问题&#xff0c;结果这次就不给过还提示我们这个。 我们的视频是操作演示的视频。仅用于介绍使用。 是否接受修改指引&#xff0c;勾选我不理解以上内容 再勾选 下面不理解内容异项 申诉理由 视频播放和观看只限于当前用户自己使用&#xff0c;而视…

Unity Lerp和InverseLerp函数用处

我认为最大的用处就是缓冲刚体移动&#xff01;&#xff01;&#xff01;它的作用是每次调用都返回一个 a &#xff08;b - a&#xff09; * t的值&#xff0c;所以只要给一个变化的t值&#xff0c;就可以得到一个适中移动速度的刚体&#xff0c;类似下面这种用法&#xff0c;…