Neo4j是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。程序员工作在一个面向对象的、灵活的网络结构下而不是严格、静态的表中——但是他们可以享受到具备完全的事务特性、企业级的数据库的所有好处。 你可以把Neo看作是一个高性能的图引擎,该引擎具有成熟和健壮的数据库的所有特性。程序员工作在一个面向对象的、灵活的网络结构下而不是严格、静态的表中——但是他们可以享受到具备完全的事务特性、企业级的数据库的所有好处。 Neo是一个网络——面向网络的数据库——也就是说,它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络上而不是表中。网络(从数学角度叫做图)是一个灵活的数据结构,可以应用更加敏捷和快速的开发模式。 Neo4j是一个嵌入式,基于磁盘的,支持完整事务的Java持久化引擎,它在图(网络)中而不是表中存储数据。Neo4j提供了大规模可扩展性,在一台机器上可以处理数十亿节点/关系/属性的图,可以扩展到多台机器并行运行。相对于关系数据库来说,图数据库善于处理大量复杂、互连接、低结构化的数据,这些数据变化迅速,需要频繁的查询——在关系数据库中,这些查询会导致大量的表连接,因此会产生性能上的问题。Neo4j重点解决了拥有大量连接的传统RDBMS在查询时出现的性能衰退问题。通过围绕图进行数据建模,Neo4j会以相同的速度遍历节点与边,其遍历速度与构成图的数据量没有任何关系。此外,Neo4j还提供了非常快的图算法、推荐系统和OLAP风格的分析,而这一切在目前的RDBMS系统中都是无法实现的。 下面介绍代码与程序 neo4j分为桌面版和不用安装的文件版 直接在官网下载即可neo4j.com/ 注意官网的速度很慢 如果有需要的可以评论区留言 neo4j增删改查
//新增数据
create(n:Mysql{name:"123",age:12})
//新增两个节点并设置关系
create(a:DD{name:"222"})-[:sss]->(m:OO{name:"sss"})
//查询某个关系可以带出此关系所以的节点
match p=()-[r:sss]->() return p
//查询数据注意查询时必须要加return,这个就不想关系型数据库啦
match(n:Mysql) return n
//查询时where条件有两种形式
match(n:Mysql{name:"123"}) return n 或者 match(n:Mysql) where n.name="123" return n
//修改
match(n:Mysql) where n.name="123" set n.name="iii"
//删除
match(n:Mysql) where n.name="iii" delete n
//如果是带有关系的那么就需要先删除关系,然后再删除节点或者使用detach delete来删除
match(n:DD) detach delete n
下面是mysql数据库直接导入到neo4j中 在进行以下语句时需要在neo4j文件夹中找到plugins,然后将apoc和mysql的驱动放入此文件下。并且需要在neo4j.conf中添加dbms.security.procedures.unrestricted=apoc.*这样才能够使用apoc算法。 并且启动neo4j访问http://127.0.0.1:7474/browser/ 首先输入call apoc.load.driver('com.mysql.jdbc.Driver')用来注明mysql驱动程序 以上步骤进行完才能够进行下面的步骤
//将第一个表导入到neo4j
CALL apoc.load.jdbc('jdbc:mysql://localhost:3306/user?user=xxx&password=xxx&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC','select * from apop') YIELD row
CREATE (n:Apop {name: row.name, id: row.a_id})
//将第二张表导入
CALL apoc.load.jdbc('jdbc:mysql://localhost:3306/user?user=xxx&password=xxx&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC','select * from peo') YIELD row
CREATE (n:Peo{name: row.name1, id: row.p_id})
//中间表为关系表,根据关系表可以将两个节点连接起来
CALL apoc.load.jdbc('jdbc:mysql://localhost:3306/user?user=xxx&password=xxx&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC','select * from pop') YIELD row
//merge是create和match的一个组合,当存在是就不会新建数据不存在时新建
merge(n:Apop{id:row.a_id})
merge(m:Peo{id:row.p_id})
merge(n)-[:关系]->(m)
最后的效果
这样就根据中间表直接的关系将两个节点连接起来。
第二种导入方法如下: 首先将csv文件放入到neo4j到import文件夹下
csv表头如下:
id,名称,物料编号,版本号
然后在neo4j浏览器中输入
LOAD CSV WITH HEADERS FROM 'file:///csv名称.csv' AS line
MERGE (c2:车辆{
id:line.id,
name:line.名称,
名称:line.名称,
物料编号:line.物料编号,
版本号:line.版本号});
LOAD CSV WITH HEADERS FROM 'file:///第二个csv.csv' AS line
MERGE (c2:厂家{
id:line.Id,
name:line.名称,
名称:line.名称})
//由于车辆节点已经建立,这个到意思是根据每一行到车辆到id对应上厂家,先去找没有就新建MERGE的意思就是有就查询没有就新建一个
MERGE (c3:车辆{id:line.车辆Id})
//创建厂家和车辆直接到关系
MERGE(c2)-[:所属]->(c3);
第三种是空库的情况下使用就是初始化数据时如果时间很多可以使用此方式,这种的方式速度很快 将csv放入import下。这里需要注意的是关系csv中需要在表头上来说明是那个表的id或者其他数据比如 :START_ID(actors),role,:END_ID(movies),:TYPE actors是节点csv的名字,movies也是一个节点csv的名字,TYPE表示关系名称 输入下面这句就可以将数据导入到csv中--nodes后面跟的是节点到csv,--relationships后面跟的是关系到csv 必须是空库的时候才能够成功
./bin/neo4j-admin import --nodes import/movies.csv --nodes import/actors.csv --relationships import/roles.csv
如果从mysql中导入数据到neo4j还有一种写法就是update的写法,当存在id时就相当于修改数据添加一些东西,当不存在时就相当于新建一条数据。
//第一张表
CALL apoc.load.jdbc('jdbc:mysql://localhost:3306/user?user=root&password=zhangxian11&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC','select * from peo') YIELD row merge (n:Peo{id: row.p_id}) set n.name1=row.name1
//第二张表
CALL apoc.load.jdbc('jdbc:mysql://localhost:3306/user?user=root&password=zhangxian11&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC','select * from apop') YIELD row
merge (n:Apop {id: row.a_id}) set n.name=row.name
//中间表
CALL apoc.load.jdbc('jdbc:mysql://localhost:3306/user?user=root&password=zhangxian11&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC','select * from pop') YIELD row
merge(n:Apop{id:row.a_id})
merge(m:Peo{id:row.p_id})
merge(n)-[:关系]->(m)
springboot+neo4j+mysql之间的导入问题 mapper类
//将某个mysql中的数据导入
@Query("CALL apoc.load.jdbc('jdbc:mysql://localhost:3306/user?user=root&password=zhangxian11&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC','select * from Apop') YIELD row merge (n:Apop {name: row.name, id: row.a_id})")
void daoru();
//将某个mysql中的数据导入
@Query("CALL apoc.load.jdbc('jdbc:mysql://localhost:3306/user?user=root&password=zhangxian11&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC','select * from peo') YIELD row merge (n:Peo{name: row.name1, id: row.p_id})")
void diergebiao();
//修改neo4j已存在的节点达到增量修改的目的,用此方法如果neo4j没有mysql新增加的数据那么就此时的修改就相当于新建一个节点,set有添加属性的意义
@Query("CALL apoc.load.jdbc('jdbc:mysql://localhost:3306/user?user=root&password=zhangxian11&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC','select * from peo') YIELD row merge (n:Peo{id: row.p_id} )set n.name1=row.name1")
void update1();
//此处是将neo4j中的节点与关系进行连接,merge的意义就是当某个数据存在时不进行新增,不存在时进行新增
@Query("CALL apoc.load.jdbc('jdbc:mysql://localhost:3306/user?user=root&password=zhangxian11&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC','select * from pop') YIELD row merge(n:Apop{id:row.a_id}) merge(m:Peo{id:row.p_id}) merge(n)-[t:sd]->(m)")
void guanxi();
}
controller
@RequestMapping("/daoru")
@ResponseBody
void daoru(){
userRepository2.daoru();
}
@RequestMapping("/diergebiao")
@ResponseBody
void deer(){
userRepository2.diergebiao();
}
@RequestMapping("/update1")
@ResponseBody
void update2(){
userRepository2.update1();
}
//将中间表中的数据作为关系的新建条件
@RequestMapping("/guanxi")
@ResponseBody
void guanxi(){
userRepository2.guanxi();
}
//此处就是从mysql中导入数据并且创建关系的一个总的过程
@RequestMapping("/zongde")
@ResponseBody
void zongde(){ userRepository2.daoru();
userRepository2.diergebiao();
userRepository2.guanxi();}
`删除节点属性: match (n:测试123) where n.code='123' REMOVE n.name
新增label
create(n:fgffdsd{name:'dddd'})
查询某个节点 match(n:测试123) where n.code='123' return n
查询某个label所有节点 match(n:测试123) return n
查询某个节点所有的关系节点 match p=(n:测试123)-[]-() return p
查询所有的节点直接的关系 match p=()-[]-() return p
带方向查询所有节点 match p=()-[]->() return p
查询出两个节点然后添加关系 match(n:test123) where n.code='123' match(m:test345) where m.code='345' create(n)-[r:role{name:'同事'}]->(m)
修改属性标签 code1为新属性标签 code为老属性标签 match(n:FSD) set n.code1=n.code remove n.code
修改属性值 match(n:FSD) where n.code1='123' set n.name='张三'
修改标签 match (n:FSD) remove n:FSD set n:FSD123
查询没有关系的节点 match (n) where not(n)-[]-() return n
多标签写法 添加: create(n:WWWED:DDFFFS:gggggg{name:'张杀杀杀'})
查询 match(n:WWWED:DDFFFS:gggggg) where n.name='张杀杀杀' return n
批量清空后添加属性(节点)
MATCH (n:刘伟豪1) SET n={title:"刑事案件性质代字",name:"dssdsd",age:12} RETURN n
批量清空后添加属性(关系)
MATCH p=()-[r:刑事案件性质代字]->() SET r={title:"刑事案件性质代字"} RETURN p
模糊查询 blog.csdn.net/weixin_4414…
MATCH (person:Person) //遍历所有 Person MERGE (city:City { name: person.bornIn }) //如果不存在 出生地的城市,则创建 MERGE (person)-[r:BORN_IN]->(city) //如果不存在关系则创建 RETURN person.name, person.bornIn, city
MERGE (keanu:Person { name: 'Keanu Reeves' }) ON CREATE SET keanu.created = timestamp() //不存在时执行 ON MATCH SET keanu.lastSeen = timestamp() //已存在时执行 RETURN keanu.name, keanu.created, keanu.lastSeen
match (a),(b) where id(a)=25 and id(b)=8
merge (a)-[r:gogogo]->(b) //如果不存在 gogogo 关系则创建
on create set r.w = 1 //当关系不存在新增关系时,增加或修改其属性
on match set r.w = 100 //当关系已存在时,增加或修改其属性
return a,b,r
match (a),(b) where id(a)=25 and id(b)=8
merge (a)-[r:gogogo]->(b) //如果不存在 gogogo 关系则创建
on create set r.w = 1 //当关系不存在时,新增关系时,增加或修改其属性
on match set r.w = coalesce(r.w, 0) + 1 //当关系已存在时,增加或修改其属性
return a,b,r
merge(n:GGGFF{name:'张三'}) 存在则不创建,不存在则创建 merge(m:HHHH{name:'李四'}) 存在则不创建,不存在则创建 merge(n)-[r:DDDDD]->(m) 存在则不创建,不存在则创建
查询节点属性key MATCH (n:Person{name:'Ernesto'}) RETURN keys(n)
MATCH (n) OPTIONAL MATCH (n)-[r]-() RETURN distinct keys(n), keys(r)
如果一次性多个修改语句需要创建事务最后提交整体事务 Transaction transaction = session.beginTransaction(); //第一步删除节点有关的所有关系 transaction.run("match(n:"+label+")-[r]-() where n.nodeTypeCommon=code delete r", parameters("nodeTypeCommon", nodeTypeCommon,"code",code)); //清除除了code和nodeTypeCommon以外的属性key transaction.run("MATCH (n:"+label+") where n.nodeTypeCommon=code WITH n, [k in keys(n) where not k in ["code","nodeTypeCommon"]] as keys CALL apoc.create.removeProperties(n, keys) YIELD node RETURN count()", parameters("nodeTypeCommon", nodeTypeCommon,"code",code)); //重新添加为改节点添加属性key transaction.run("MATCH (n:"+label+") where n.nodeTypeCommon=code SET n="+values+" RETURN n", parameters("nodeTypeCommon", nodeTypeCommon,"code",code)); //新增关系 for(int i =0;i<relationship.size();i++){ String relationshipAttr = relationship.getJSONObject(i).getStr("relationshipAttribute"); String startCode = relationship.getJSONObject(i).getStr("startCode"); String endCode = relationship.getJSONObject(i).getStr("endCode"); String relationshipAttribute = relationshipAttr.replaceAll(""(\w+)"(\s:\s*)", "2"); transaction.run("MATCH (n) WHERE n.code = nodeTypeCommon \n" + "MATCH (m) WHERE m.code = nodeTypeCommon \n" + "create(n)-[r:relationship"+relationshipAttribute+"]->(m)" , parameters("startCode", startCode,"endCode",endCode,"nodeTypeCommon",nodeTypeCommon)); } //手动提交事务 transaction.commit();`