一、Neo4j介绍
1、随着社交、金融、零售等行业的发展,现实社会织起了一个庞大而复杂的关系网,采用图数据来处理它,会更高效、更方便,图数据库更擅长支持海量、复杂、多变的关系运算,并且运算性能非常高,在后续的笔记会记录图数据库的其他特性
二、Neo4j基于windows系统环境搭建
1、Neo4j需要jdk11或以上版本,如果本地环境不满足的话,先安装jdk11
2、下载Neo4j最新社区版,下载后复制到自定义目录中解压
3、配置环境变量
3.1、打开环境变量窗口
3.2、在用户环境变量添加变量,变量值引用Neo4j所在目录
3.3、在系统环境变量中设置
3.4、环境变量配置好后,在命令提示窗口输入neo4j.bat console命令验证,出现如下图所示则安装成功
3.5、复制倒数第二行地址http://localhost:7474/在浏览器中打开,默认用户名和密码为neo4j和neo4j,之后会提示修改密码,不要忘记密码
3.6、至此,便成功安装好Neo4j了。
(命令行窗口不可以关闭,需持续打开状态才能成功进入Neo4j的网页)
3.7、安装过程中用到的安装包
链接:https://pan.baidu.com/s/11XoKULqKev8GJaJCFqMyKw
提取码:73zw
三、Neo4j简单语法使用
1、创建节点:
create(s:Student{name:"熊熊"}) return s
create(g:Group{name:"高一班"}) return g
2、节点查询
2.1、查询全部节点
match(n) return n
2.2、查询全部的前N个节点
match(n) return n limit 3
2.3、查询某类型的节点,例如查询所有学生节点
match(s:Student) return s
3、建立关联关系
3.1、建立班级学生关系:例如班级管理学生
match(g:Group{name:"高一班"}),(s:Student{name:"熊熊"}) create (g)-[r:管理]->(s) return g,s
4、解除关联关系
有时候因为某种原因,关系建立错了,例如:
match(s:Student{name:"熊熊"}),(g:Group{name:"高一班"}) create (s)-[r:`管理`]->(g) return s,g
这种情况就需把这条错误的关系删除,请看删除关系:
match(g:Group)r:`管理`]-(s:Student) where g.name="高一班" and s.name="熊熊" delete r return g,s,r
5、删除某个节点
先查询出节点 match(p:Persion) return p limit 100
写法1:match(p:Persion) where p.name="张三" delete p
写法2:match(p:Persion{name:"李四"}) delete p
6、修改
match(s:Student) where s.name="熊熊" set s.name="雄哥" return s
在后续学习中会详细记录Neo4j语法,此处先简单做一些增删改查操作
四、spring boot 集成neo4j
1、创建boot工程
2、pom文件
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>neo4j-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
<version>2.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.12.6</version>
</dependency>
</dependencies>
</project>
3、创建实体类
package com.neo.demo.domain;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import java.io.Serializable;
@NodeEntity("Person")
public class Person implements Serializable {
@Id
@GeneratedValue
private Long id;
private String name;
public String getName() {
return name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
4、基于spring data,创建dao
package com.neo.demo.dao;
import com.neo.demo.domain.Person;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface PersonRepository extends Neo4jRepository<Person,Long> {
@Query("match(p:Person{name:$name}) delete p ")
void removePersonByName(@Param("name") String name);
@Query("match(p:Person{name:$oldName}) set p.name=$newName return p ")
Person updatePersonNameById(@Param("oldName") String oldName,@Param("newName") String newName);
}
5、创建controller
package com.neo.demo.controller;
import com.neo.demo.dao.PersonRepository;
import com.neo.demo.domain.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import sun.java2d.pipe.SpanClipRenderer;
import java.util.Map;
@RestController
@RequestMapping("/person")
public class PersonController {
@Autowired
private PersonRepository repository;
@PostMapping("/savePerson")
public Object savePerson(@RequestBody Person param){
Person person = new Person();
person.setName(param.getName());
return repository.save(person);
}
@DeleteMapping("/removePersonById")
public String removePersonById(Long personId){
try {
repository.deleteById(personId);
return "删除成功";
}catch (Exception e ){
e.printStackTrace();
return "删除异常";
}
}
@DeleteMapping("/removePersonByName")
public String removePersonByName(String name){
try {
repository.removePersonByName(name);
return "操作成功";
}catch (Exception e){
e.printStackTrace();
return "通过person name 删除异常";
}
}
@PutMapping("/updateById")
public Person updateById(@RequestBody Map<String,String> person){
return repository.updatePersonNameById(person.get("oldName"),person.get("newName"));
}
}
6、通过代码操作关联关系
6.1、绑定关系类
package com.neo.demo.domain;
import org.neo4j.ogm.annotation.*;
@RelationshipEntity(type = "师徒")
public class PersonRelation {
@Id
@GeneratedValue
private Long id;
@StartNode
private Person parent;
@EndNode
private Person child;
public Person getParent() {
return parent;
}
public void setParent(Person parent) {
this.parent = parent;
}
public Person getChild() {
return child;
}
public void setChild(Person child) {
this.child = child;
}
}
6.2、绑定关系dao
package com.neo.demo.dao;
import com.neo.demo.domain.PersonRelation;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface PersonRelationRepository extends Neo4jRepository<PersonRelation,Long> {
@Query("match(p:Person{name:$parentName})-[r:`师徒`]->(pp:Person{name:$childName}) delete r")
void relievePersonRelation(@Param("parentName") String parentName, @Param("childName") String childName,@Param("relation") String relation);
}
6.3、controller调用代码
@PostMapping("/createPersonRelation")
public PersonRelation createPersonRelation(@RequestBody PersonRelationVo vo){
PersonRelation relation = new PersonRelation();
Person parentPerson = repository.selectPersonByName(vo.getParent());
Person childPerson = repository.selectPersonByName(vo.getChild());
if(Objects.isNull(parentPerson)){
parentPerson = new Person();
parentPerson.setName(vo.getParent());
repository.save(parentPerson);
}
if(Objects.isNull(childPerson)){
childPerson = new Person();
childPerson.setName(vo.getChild());
repository.save(childPerson);
}
relation.setParent(parentPerson);
relation.setChild(childPerson);
return relationRepository.save(relation);
}
@PostMapping("/relieve")
public String relieve(@RequestBody PersonRelationVo vo){
try {
relationRepository.relievePersonRelation(vo.getParent(),vo.getChild(),"师徒");
return "解除成功";
}catch (Exception e){
e.printStackTrace();
return "解除失败";
}
}
7、查询
7.1、查询某个节点的子节点,例如:查询雄霸的所有弟子
/**
* 查询某个人的所有徒弟
* @param name 师傅名称
* @return 徒弟
*/
@Query("match(p:Person{name:$name})-[r:`师徒`]->(pp:Person) return pp ")
List<Person> selectChildByParentName(@Param("name") String name);
7.2、controller调用
/**
* 查询某个节点的子节点
* 示例:查询某个人的所有徒弟
* @return 子节点
*/
@GetMapping("/findChildByParentName")
public List<Person> findChildByParentName(String name){
return repository.selectChildByParentName(name);
}
7.3、postman测试
7.4、查询一个人的父节点
例:查询步惊云的所有师傅
/**
* 查询某个人的所有师傅
* @param name 徒弟名称
* @return 师傅
*/
@Query("match(p:Person{name:$name})<-[r:`师徒`]-(p1:Person) return p1 ")
List<Person> selectParentByChildName(@Param("name") String name);
/**
* 查询父节点
* @param name 子节点名称
* @return 所有的父节点
*/
@GetMapping("/findParentByChildName")
public List<Person> findParentByChildName(String name){
return repository.selectParentByChildName(name);
}
注意:运行过程中有可能会报JSON parse error: Cannot construct instance of错误
原因是当实体类没有默认构造器时候,发送json参数会报错