1、拉取镜像
docker pull neo4j:4.2
2、运行镜像
docker run -it -d -p 7474:7474 -p 7687:7687 neo4j:4.2
3、通过csv导入数据到neo4j中
LOAD CSV WITH HEADERS FROM 'file:///bbc.csv' AS line
CREATE (:Artist { name: line.NAME, flalt: toInteger(line.ID)})
4、常用操作
创建节点:
CREATE (friend:Person {name: 'Mark'}) 说明:friend是节点名称,Person是标签名称
RETURN friend
创建节点和关系
MATCH (jennifer:Person {name: 'Jennifer'})
MATCH (mark:Person {name: 'Mark'})
CREATE (jennifer)-[rel:IS_FRIENDS_WITH]->(mark)
//this query will create duplicate nodes for Mark and Jennifer
CREATE (j:Person {name: 'Jennifer'})-[rel:IS_FRIENDS_WITH]->(m:Person {name: 'Mark'})
带标签的关系
create (n:Person{name:"Lee"})-[r:R{type:"朋友"}]->(m:Person{name:"LiLy"}) return n,r,m 其中, n和Person是节点名称和节点标签名称,属于“From Node” m和Person是“To Node”的节点名称和节点标签名称 r是关系名称,朋友是一个关系标签名称
创建多个关系示例
MATCH (a:Artist),(b:Album),(p:Person) WHERE a.name = "筷子兄弟" AND b.name = "猛龙过江" AND p.name = "王太利" CREATE (p)-[:PRODUCED]->(b), (p)-[:PERFORMED_ON]->(b), (p)-[:PLAYS_IN]->(a) RETURN a,b,p
更新数据
MATCH (p:Person {name: 'Jennifer'})
SET p.birthdate = date('1980-01-01')
RETURN p
删除关系
MATCH (j:Person {name: 'Jennifer'})-[r:IS_FRIENDS_WITH]->(m:Person {name: 'Mark'})
DELETE r
删除节点
MATCH (m:Person {name: 'Mark'})
DELETE m
删除节点和关系
MATCH (m:Person {name: 'Mark'})
DETACH DELETE m
//delete property using REMOVE keyword
MATCH (n:Person {name: 'Jennifer'})
REMOVE n.birthdate
删除属性
//delete property with SET to null value
MATCH (n:Person {name: 'Jennifer'})
SET n.birthdate = null
在节点上使用合并
MERGE (mark:Person {name: 'Mark'})
RETURN mark
在关系上使用合并
MATCH (j:Person {name: 'Jennifer'})
MATCH (m:Person {name: 'Mark'})
MERGE (j)-[r:IS_FRIENDS_WITH]->(m)
RETURN j, r, m
创建关系
LOAD CSV WITH HEADERS FROM "file:///rel.csv" AS line
match (from:Empleer01{id:line.START}),(to:Empleer02{id:line.END})
merge (from)-[r:line.TYPE]->(to)
清除所有数据
match (n) detach delete n
5、说明
如果要查看系统信息(查看,创建/删除,管理数据库),则需要切换到system
数据库。我们可以使用:use
命令来做到这一点,然后告诉它我们想要哪个数据库。
命令: use system
show databases
请记住,此时,我们只希望使用system
数据库和默认(neo4j
)数据库。
创建数据库
create database movie
注意:数据库命名不区分大小写
确认该数据库是否有数据
CALL db.schema.visualization()
6、数据模型转换技巧
让我们看一下关系数据模型中的一些关键组件,并将它们转换为图形数据模型的组件。下面列出了帮助您转换关系图的步骤。
-
表到节点标签-关系模型中的每个实体表都成为图模型中节点上的标签。
-
行到节点-关系实体表中的每一行都成为图中的一个节点。
-
列到节点的属性-关系表上的列(字段)成为图中的节点属性。
-
仅限业务主键-删除技术主键,保留业务主键。
-
添加约束/索引-为业务主键添加唯一约束,为频繁查找属性添加索引。
-
关系的外键-用关系替换到另一个表的外键,然后将其删除。
-
无默认值-删除具有默认值的数据,无需存储这些值。
-
清理数据-非规范化表中的重复数据可能必须被拉到单独的节点中以获得更清晰的模型。
-
数组的索引列-索引列名称(例如email1,email2,email3)可能表示数组属性。
-
将表联接到关系-将联接表转换为关系,这些表上的列成为关系属性
7、导入数据方法
导入csv
导入json:https://neo4j.com/developer/guide-import-json-rest-api/
导入rdbms到neo4j数据库中:https://neo4j.com/developer/relational-to-graph-import/
8、springboot整合neo4j示例
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-neo4j</artifactId> </dependency> </dependencies>
spring.data.neo4j.uri=neo4j://localhost spring.data.neo4j.username=neo4j spring.data.neo4j.password=Testing123 #does not open a session when a request comes in #SpringBoot defaults this to true, opens a read/write session for OGM # which makes all transactions read/write, even on queries marked as read-only # That can cause issues in a Neo4j cluster because writes are sent only to the leader in the cluster #With this property set to false, recognizes read-only requests and can send to read replicas spring.data.neo4j.open-in-view=false
@NodeEntity public class Person { @Id @GeneratedValue private Long id; private String name; @Property("born") private int birthyear; } @NodeEntity public class Movie { @Id @GeneratedValue private Long id; private String title; private int released; @Property("tagline") private String description; }
@RelationshipEntity(type = "ACTED_IN") public class Role { @Id @GeneratedValue private Long id; private List<String> roles = new ArrayList<>(); @StartNode private Person person; @EndNode private Movie movie; }
@NodeEntity public class Person { .... @Relationship(type = "ACTED_IN") private List<Role> actedIn = new ArrayList<>(); @Relationship(type = "DIRECTED") private List<Movie> directed = new ArrayList<>(); } @NodeEntity public class Movie { .... @Relationship(type = "ACTED_IN", direction = INCOMING) private List<Role> actors = new ArrayList<>(); @Relationship(type = "DIRECTED", direction = INCOMING) private List<Person> directors = new ArrayList<>(); }
@NodeEntity public class Person { .... @JsonIgnoreProperties("person") @Relationship(type = "ACTED_IN") private List<Role> actedIn = new ArrayList<>(); @JsonIgnoreProperties({"actors", "directors"}) @Relationship(type = "DIRECTED") private List<Movie> directed = new ArrayList<>(); } @NodeEntity public class Movie { .... @JsonIgnoreProperties("movie") @Relationship(type = "ACTED_IN", direction = INCOMING) private List<Role> actors = new ArrayList<>(); @JsonIgnoreProperties({"actedIn", "directed"}) @Relationship(type = "DIRECTED", direction = INCOMING) private List<Person> directors = new ArrayList<>(); } @RelationshipEntity(type = "ACTED_IN") public class Role { .... @StartNode @JsonIgnoreProperties({"actedIn", "directed"}) private Person person; @EndNode @JsonIgnoreProperties({"actors", "directors"}) private Movie movie; }
public interface PersonRepository extends Neo4jRepository<Person, Long> { } public interface MovieRepository extends Neo4jRepository<Movie, Long> { }
public interface PersonRepository extends Neo4jRepository<Person, Long> { Person getPersonByName(String name); Iterable<Person> findPersonByNameLike(String name); @Query("MATCH (am:Movie)<-[ai:ACTED_IN]-(p:Person)-[d:DIRECTED]->(dm:Movie) return p, collect(ai), collect(d), collect(am), collect(dm)") List<Person> getPersonsWhoActAndDirect(); }
public interface MovieRepository extends Neo4jRepository<Movie, Long> { Movie getMovieByTitle(String title); Iterable<Movie> findMovieByTitleLike(String title); }
https://neo4j.com/developer/spring-data-neo4j/
参考示例:https://github.com/neo4j-examples/spring-data-neo4j-intro-app/tree/master/src
9、如何在自定义查询中指定参数
您执行此操作的方式与在Neo4j浏览器或Cypher-Shell中发出的标准Cypher查询中的$
语法完全相同(使用Neo4j 4.0以上版本的{foo}
Cypher参数的旧语法已从数据库中删除);
public interface ARepository extends Neo4jRepository<AnAggregateRoot, String> { @Query("MATCH (a:AnAggregateRoot {name: $name}) RETURN a") Optional<AnAggregateRoot> findByCustomQuery(String name); }
10、根据节点名称查询关系节点
package com.hgchain.neo4j.data.nodes; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.neo4j.ogm.annotation.*; import java.util.List; /** * @Auther liubh * @date 2020/11/24 17:18 **/ @RelationshipEntity(type = "R") @Data @NoArgsConstructor @AllArgsConstructor public class Relationships { private String name; private String type; @StartNode private Empleer01 empleer01; @EndNode private Empleer02 empleer02; }
package com.hgchain.neo4j.data.dao; import com.hgchain.neo4j.data.nodes.Empleer01; import com.hgchain.neo4j.data.nodes.Empleer02; import com.hgchain.neo4j.data.nodes.Relationships; import com.hgchain.neo4j.data.repose.NodeResponse; 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.Component; import org.springframework.stereotype.Repository; import java.util.List; @Repository public interface EmpleerReposity extends Neo4jRepository<Empleer02,Long> { @Query("match(e:Empleer02{name:$name})-[r:R]-(n:Empleer01) return e AS empleer02 ,r AS relationships,n AS empleer01") List<Relationships> findByName(String name); }