当前位置:   article > 正文

Neo4j和Cypher快速入门

Neo4j和Cypher快速入门

  一、Neo4j快速入门

1.1.什么是Neoj4?

Neo4j是用Java实现的开源NoSQL图数据库。从2003年开始开发,2007年正式发布第一版,其源码托管于GitHtb。Neo4j作为图数据库中的代表产品,已经在众多的行业项目中进行了应用,如:网络管理、软件分析、组织和项目管理、社交项目等方面。

官网:Neo4j Graph Database & Analytics | Graph Database Management System

Neo4j实现了专业数据库级别的图数据模型的存储,提供了完整的数据库特性,包括ACID事务的支持、集群的支持、备份和故障转移等。

Neo4j提供了申明式的查询语言Cypher,它类似于关系型数据库中的SQL语言,其具有表现力丰富、使用简单、查询效率高、高扩展性等特点。

它存储的数据大致是这样的:

其中,紫色圆圈是【人】数据,橙色圆圈是【电影】数据,表示人与电影之间参演或导演的数据关系。 

 1.2.版本说明

Neo4j有两个不同的版本,分别是:

  • 社区版(Community Edition)
    • 具备了基本功能的版本,功能较为完整,没有提供企业服务。
  • 企业版(Experience Edition)
    • 企业版相对于社区版而言,增加了一些功能,如:集群、高级监控、高级缓存、在线备份等功能。

建议:开发环境使用社区版,生产环境使用企业版。

说明:企业版从3.2版本开始支持集群,无地理位置限制并且可以做到事务的ACID特性。

Neo4j企业·参考:Neo4j 企业版 价格表 - Neo4j 图数据库中文社区

 1.3.部署安装

 Neo4j支持众多平台的部署安装,如:Windows、Mac、Linux等系统。Neo4j是基于Java平台的,所以部署安装前先保证已经安装了Java虚拟机。

 这里我们采用docker的方式进行安装。安装命令如下:

  1. docker run \
  2. -d \
  3. --restart=always \
  4. --name neo4j \
  5. -p 7474:7474 \
  6. -p 7687:7687 \
  7. -v neo4j:/data \
  8. neo4j:4.4.5
  9. # 7474是web管理工具的端口,7687是neo4j协议端口进行数据通信

打开浏览器,输入地址:http://neo4j.sl-express.com/browser/

如果是第一次登录,用户名:neo4j,默认密码是:neo4j,首次登录需要重置密码:

登录成功后可以看到如下界面: 

 1.4.Neo4j web工具介绍

 Neo4j提供了web工具,可以对neo4j进行CRUD的操作。

 

 1.5.体验Neo4j

下面我们通过官方提供的电影数据体验下Neo4j:

 

 运行语句创建

 1.6.查询数据

查询【Tom Hanks】参演了哪些电影:

MATCH (tom:Person {name: "Tom Hanks"})-[:ACTED_IN]->(tomHanksMovies) RETURN tom,tomHanksMovies

1.7.数据结构

 

  • 节点
    • 存储实体数据,在上图中,演员、电影都是节点。
    • 可以理解为关系型数据库中的表。
  • 关系
    • 存储节点之间的关系。
    • 关系只能有一个类型,必须有开始节点和结束节点以及指向。
    • 关系可以自我循环引用,但是两头永远不能为空。
  • 属性
    • 节点和关系都可以有属性,它是由键值对组成的。
    • 节点的属性可以理解为关系型数据库中的字段。
    • 关系中的属性进一步的明确了关系。
  • 标签
    • 标签是对节点的分类,这样使得构建Neo4j数据模型更加简单。
    • 在上面的电影案例中,Movie、Person就是标签

二、Cypher快速入门 

Cypher是Neo4j的查询语言,类似与关系型数据库中的SQL,一些关键词来源于SQL,比如:CREATE、WHERE、RETRUN等。下面我们一起学习Cypher的基本语句。

Cypher语句的关键字对大小写不敏感。

 2.1.创建数据

 在Neo4j中使用CREATE命令来创建节点、关系、属性数据。语法如下:

  1. //查询所有数据
  2. MATCH (n) RETURN n
  3. //删除所有节点和关系,慎用!
  4. MATCH (n) DETACH DELETE n
  5. CREATE (n {name: $value}) RETURN n //创建节点,该节点具备name属性,n为该节点的变量,创建完成后返回该节点
  6. CREATE (n:$Tag {name: $value}) //创建节点,指定标签
  7. CREATE (n)-[r:KNOWS]->(m) //创建n指向m的关系,并且指定关系类型为:KNOWS
  8. //示例
  9. CREATE (n {name:'迪士尼营业部'})
  10. CREATE (n:AGENCY {name:'航头营业部'})
  11. //创建浦东新区转运中心、上海转运中心节点,并且创建关系为:IN_LINE,创建完成后返回节点和关系
  12. //TLT -> Two Level Transport(二级转运中心)
  13. //OLT -> One Level Transport(一级转运中心)
  14. CREATE (n:TLT {name:'浦东新区转运中心'}) -[r:IN_LINE]-> (m:OLT {name:'上海转运中心'}) RETURN n,r,m
  15. //关系也是可以反向,并且可以为关系中指定属性
  16. CREATE (n:TLT {name:'浦东新区转运中心'}) <-[r:OUT_LINE]- (m:OLT {name:'上海转运中心'}) RETURN n,r,m

 2.2.查询数据

Cypher查询语法如下:

  1. [MATCH WHERE] //条件查询
  2. [WITH [ORDER BY] [SKIP] [LIMIT]] //查询的结果以管道的形式传递给下面的语句,聚合查询必须使用WITH
  3. RETURN [ORDER BY] [SKIP] [LIMIT] //返回、排序、跳过、返回个数

2.3.构造数据

  1. CREATE (北京市转运中心:OLT {bid: 8001, name: "北京市转运中心", address: "北京市转运中心", location : point({latitude:39.904179, longitude:116.407387})})
  2. CREATE (上海市转运中心:OLT {bid: 8002, name: "上海市转运中心", address: "上海市转运中心", location : point({latitude:31.230525, longitude:121.473667})})
  3. CREATE (南京市转运中心:OLT {bid: 8003, name: "南京市转运中心", address: "南京市转运中心", location : point({latitude:32.059344, longitude:118.796624})})
  4. CREATE (太原市转运中心:OLT {bid: 8004, name: "太原市转运中心", address: "太原市转运中心", location : point({latitude:37.870451, longitude:112.549656})})
  5. CREATE (郑州市转运中心:OLT {bid: 8005, name: "郑州市转运中心", address: "郑州市转运中心", location : point({latitude:34.745551, longitude:113.624321})})
  6. CREATE
  7. (北京市转运中心)-[:IN_LINE {cost:10684.9}]->(上海市转运中心),
  8. (北京市转运中心)<-[:OUT_LINE {cost:10684.9}]-(上海市转运中心),
  9. (北京市转运中心)-[:IN_LINE {cost:8993.1}]->(南京市转运中心),
  10. (北京市转运中心)<-[:OUT_LINE {cost:8993.1}]-(南京市转运中心),
  11. (南京市转运中心)-[:IN_LINE {cost:2699.4}]->(上海市转运中心),
  12. (南京市转运中心)<-[:OUT_LINE {cost:2699.4}]-(上海市转运中心),
  13. (太原市转运中心)-[:IN_LINE {cost:3609.7}]->(郑州市转运中心),
  14. (太原市转运中心)<-[:OUT_LINE {cost:3609.7}]-(郑州市转运中心),
  15. (郑州市转运中心)-[:IN_LINE {cost:5659.7}]->(南京市转运中心),
  16. (郑州市转运中心)<-[:OUT_LINE {cost:5659.7}]-(南京市转运中心)
  17. CREATE (昌平区转运中心:TLT {bid: 90001, name: "昌平区转运中心", address: "昌平区转运中心", location : point({latitude:40.220952, longitude:116.231034})})
  18. CREATE (北京市昌平区新龙城:AGENCY {bid: 100260, name: "北京市昌平区新龙城", address: "龙跃苑四区3号楼底商", phone : "010-53049073,010-53576707", location : point({latitude:40.07544443596149, longitude:116.3470535709328})})
  19. CREATE
  20. (北京市昌平区新龙城)-[:IN_LINE {cost:189.7}]->(昌平区转运中心),
  21. (北京市昌平区新龙城)<-[:OUT_LINE {cost:189.7}]-(昌平区转运中心)
  22. CREATE (北京市昌平区定泗路:AGENCY {bid: 100280, name: "北京市昌平区定泗路", address: "北七家镇定泗路苍龙街交叉口", phone : "010-86392987", location : point({latitude:40.11765281246394, longitude:116.37212849638287})})
  23. CREATE
  24. (北京市昌平区定泗路)-[:IN_LINE {cost:166.2}]->(昌平区转运中心),
  25. (北京市昌平区定泗路)<-[:OUT_LINE {cost:166.2}]-(昌平区转运中心)
  26. CREATE (海淀区转运中心:TLT {bid: 90002, name: "海淀区转运中心", address: "海淀区转运中心", location : point({latitude:39.959893, longitude:116.2977})})
  27. CREATE (北京市海淀区小营:AGENCY {bid: 100347, name: "北京市海淀区小营", address: "北京市昌平区回龙观街道金燕龙大厦停车场", phone : "010-86483817,010-86483817,010-86483817", location : point({latitude:40.06177798692319, longitude:116.32706587559049})})
  28. CREATE
  29. (北京市海淀区小营)-[:IN_LINE {cost:116.1}]->(海淀区转运中心),
  30. (北京市海淀区小营)<-[:OUT_LINE {cost:116.1}]-(海淀区转运中心)
  31. CREATE (北京市海淀区万泉河:AGENCY {bid: 100227, name: "北京市海淀区万泉河", address: "北京市海淀区四季青镇杏石口路47号院", phone : "18521852356", location : point({latitude:39.94882822425318, longitude:116.25707017441161})})
  32. CREATE
  33. (北京市海淀区万泉河)-[:IN_LINE {cost:36.8}]->(海淀区转运中心),
  34. (北京市海淀区万泉河)<-[:OUT_LINE {cost:36.8}]-(海淀区转运中心)
  35. CREATE
  36. (昌平区转运中心)-[:IN_LINE {cost:383.3}]->(北京市转运中心),
  37. (昌平区转运中心)<-[:OUT_LINE {cost:383.3}]-(北京市转运中心),
  38. (海淀区转运中心)-[:IN_LINE {cost:112.3}]->(北京市转运中心),
  39. (海淀区转运中心)<-[:OUT_LINE {cost:112.3}]-(北京市转运中心)
  40. CREATE (浦东新区转运中心:TLT {bid: 90003, name: "浦东新区转运中心", address: "浦东新区转运中心", location : point({latitude:31.221461, longitude:121.544346})})
  41. CREATE (上海市浦东新区南汇:AGENCY {bid: 210057, name: "上海市浦东新区南汇", address: "园春路8号", phone : "18821179169", location : point({latitude:31.035240152911637, longitude:121.73459966751048})})
  42. CREATE
  43. (上海市浦东新区南汇)-[:IN_LINE {cost:275.4}]->(浦东新区转运中心),
  44. (上海市浦东新区南汇)<-[:OUT_LINE {cost:275.4}]-(浦东新区转运中心)
  45. CREATE (上海市浦东新区周浦:AGENCY {bid: 210127, name: "上海市浦东新区周浦", address: "川周公路3278-8号", phone : "021-68060322", location : point({latitude:31.132409729356993, longitude:121.59815370294322})})
  46. CREATE
  47. (上海市浦东新区周浦)-[:IN_LINE {cost:111.6}]->(浦东新区转运中心),
  48. (上海市浦东新区周浦)<-[:OUT_LINE {cost:111.6}]-(浦东新区转运中心)
  49. CREATE (奉贤区转运中心:TLT {bid: 90004, name: "奉贤区转运中心", address: "奉贤区转运中心", location : point({latitude:30.918406, longitude:121.473945})})
  50. CREATE (上海市奉贤区东部:AGENCY {bid: 210017, name: "上海市奉贤区东部", address: "上上海市奉贤区洪庙镇洪兰路351", phone : "021-57171717", location : point({latitude:30.917752751719863, longitude:121.67587819184698})})
  51. CREATE
  52. (上海市奉贤区东部)-[:IN_LINE {cost:192.9}]->(奉贤区转运中心),
  53. (上海市奉贤区东部)<-[:OUT_LINE {cost:192.9}]-(奉贤区转运中心)
  54. CREATE (上海市奉贤区青村:AGENCY {bid: 210442, name: "上海市奉贤区青村", address: "姚家村1127号", phone : "021-57566663,021-57566606", location : point({latitude:30.916946897994983, longitude:121.57954144207972})})
  55. CREATE
  56. (上海市奉贤区青村)-[:IN_LINE {cost:100.9}]->(奉贤区转运中心),
  57. (上海市奉贤区青村)<-[:OUT_LINE {cost:100.9}]-(奉贤区转运中心)
  58. CREATE
  59. (浦东新区转运中心)-[:IN_LINE {cost:68.0}]->(上海市转运中心),
  60. (浦东新区转运中心)<-[:OUT_LINE {cost:68.0}]-(上海市转运中心),
  61. (奉贤区转运中心)-[:IN_LINE {cost:347.4}]->(上海市转运中心),
  62. (奉贤区转运中心)<-[:OUT_LINE {cost:347.4}]-(上海市转运中心)
  63. CREATE (玄武区转运中心:TLT {bid: 90004, name: "玄武区转运中心" , location : point({latitude:32.048644, longitude:118.797779})})
  64. CREATE (江苏省南京市玄武区紫金墨香苑:AGENCY {bid: 25073, name: "江苏省南京市玄武区紫金墨香苑", address: "栖霞区燕尧路100号", phone : "025-58765331,025-83241955,025-83241881", location : point({latitude:32.117016089520305, longitude:118.86319310255513})})
  65. CREATE
  66. (江苏省南京市玄武区紫金墨香苑)-[:IN_LINE {cost:98.0}]->(玄武区转运中心),
  67. (江苏省南京市玄武区紫金墨香苑)<-[:OUT_LINE {cost:98.0}]-(玄武区转运中心)
  68. CREATE (江苏省南京市玄武区长江路:AGENCY {bid: 25023, name: "江苏省南京市玄武区长江路", address: "观音阁10号", phone : "18521133265,18695799166", location : point({latitude:32.04803554410631, longitude:118.79190455263355})})
  69. CREATE
  70. (江苏省南京市玄武区长江路)-[:IN_LINE {cost:5.6}]->(玄武区转运中心),
  71. (江苏省南京市玄武区长江路)<-[:OUT_LINE {cost:5.6}]-(玄武区转运中心)
  72. CREATE
  73. (玄武区转运中心)-[:IN_LINE {cost:12.0}]->(南京市转运中心),
  74. (玄武区转运中心)<-[:OUT_LINE {cost:12.0}]-(南京市转运中心)
  75. CREATE (小店区转运中心:TLT {bid: 90005, name: "小店区转运中心" , location : point({latitude:37.736865, longitude:112.565524})})
  76. CREATE (山西省太原市青龙:AGENCY {bid: 351068, name: "山西省太原市青龙", address: "长治路33号经典家园停车场内13号商铺", phone : "0351-2025888", location : point({latitude:37.83589608758359, longitude:112.56059258109424})})
  77. CREATE
  78. (山西省太原市青龙)-[:IN_LINE {cost:110.3}]->(小店区转运中心),
  79. (山西省太原市青龙)<-[:OUT_LINE {cost:110.3}]-(小店区转运中心)
  80. CREATE (山西省太原市长风街:AGENCY {bid: 351045, name: "山西省太原市长风街", address: "平阳路104号省农机公司院内", phone : "18636100730", location : point({latitude:37.809964384001226, longitude:112.55299317699505})})
  81. CREATE
  82. (山西省太原市长风街)-[:IN_LINE {cost:82.1}]->(小店区转运中心),
  83. (山西省太原市长风街)<-[:OUT_LINE {cost:82.1}]-(小店区转运中心)
  84. CREATE
  85. (小店区转运中心)-[:IN_LINE {cost:149.4}]->(太原市转运中心),
  86. (小店区转运中心)<-[:OUT_LINE {cost:149.4}]-(太原市转运中心)
  87. CREATE (中原区转运中心:TLT {bid: 90006, name: "中原区转运中心" , location : point({latitude:34.74828, longitude:113.612966})})
  88. CREATE (河南省郑州市郑上路:AGENCY {bid: 371067, name: "河南省郑州市郑上路", address: "中原西路西四环西北角", phone : "0371-55116757,0371-68014786", location : point({latitude:34.74753024533005, longitude:113.57428550005442})})
  89. CREATE
  90. (河南省郑州市郑上路)-[:IN_LINE {cost:35.4}]->(中原区转运中心),
  91. (河南省郑州市郑上路)<-[:OUT_LINE {cost:35.4}]-(中原区转运中心)
  92. CREATE (河南省郑州市颍河路:AGENCY {bid: 371086, name: "河南省郑州市颍河路", address: "航海西路与西三环交叉口向南300米路西中贸商务", phone : "19139415556", location : point({latitude:34.71593280680163, longitude:113.60398506929064})})
  93. CREATE
  94. (河南省郑州市颍河路)-[:IN_LINE {cost:36.9}]->(中原区转运中心),
  95. (河南省郑州市颍河路)<-[:OUT_LINE {cost:36.9}]-(中原区转运中心)
  96. CREATE
  97. (中原区转运中心)-[:IN_LINE {cost:11.5}]->(郑州市转运中心),
  98. (中原区转运中心)<-[:OUT_LINE {cost:11.5}]-(郑州市转运中心)

2.4.基本查询

  1. MATCH (n) RETURN n //查询所有的数据,数据量大是勿用
  2. MATCH (n:AGENCY) RETURN n //查询所有的网点(AGENCY)
  3. MATCH (n:OLT {name: "北京市转运中心"}) -- (m) RETURN n,m //查询所有与“北京市转运中心”有关系的节点
  4. MATCH (n:OLT {name:"北京市转运中心"}) --> (m:OLT) RETURN n,m //查询所有"北京市转运中心"关联的一级转运中心
  5. MATCH (n:OLT {name:"北京市转运中心"}) -[r:IN_LINE]- (m) RETURN n,r,m //可以指定关系标签查询
  6. MATCH p = (n:OLT {name:"北京市转运中心"}) --> (m:OLT) RETURN p //将查询赋值与变量
  7. //通过 type()函数查询关系类型
  8. MATCH (n:OLT {name:"北京市转运中心"}) -[r]-> (m:OLT {name:"南京市转运中心"}) RETURN type(r)

2.5.关系深度查询

可以指定关系的深度进行查询,语法格式:-[:TYPE*minHops..maxHops]->

六度分隔(Six Degrees of Separation)理论。

1967年,哈佛大学的心理学教授Stanley Milgram(1933~1984)想要描绘一个连结人与社区的人际连系网。做过一次连锁信实验,结果发现了“六度分隔”现象。简单地说:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过六个人你就能够认识任何一个陌生人。”

  1. //查询【北京市转运中心】关系中深度为1~2层关系的节点
  2. MATCH (n:OLT {name:"北京市转运中心"}) -[*1..2]->(m) RETURN *
  3. //也可以这样
  4. MATCH (n:OLT {name:"北京市转运中心"}) -[*..2]->(m) RETURN *
  5. //也可以通过变量的方式查询
  6. MATCH path = (n:OLT {name:"北京市转运中心"}) -[*..2]->(m)
  7. RETURN path
  8. //查询关系,relationships()获取结果中的关系,WITH向后传递数据
  9. MATCH path = (n:OLT {name:"北京市转运中心"}) -[*..2]->(m)
  10. WITH n,m, relationships(path) AS r
  11. RETURN r
  12. //查询两个网点之间所有的路线,最大深度为6,可以查询到2条路线
  13. MATCH path = (n:AGENCY) -[*..6]->(m:AGENCY)
  14. WHERE n.name = "北京市昌平区定泗路" AND m.name = "上海市浦东新区南汇"
  15. RETURN path
  16. //查询两个网点之间最短路径,查询深度最大为10
  17. MATCH path = shortestPath((n:AGENCY) -[*..10]->(m:AGENCY))
  18. WHERE n.name = "北京市昌平区定泗路" AND m.name = "上海市浦东新区南汇"
  19. RETURN path
  20. //查询两个网点之间所有的路线中成本最低的路线,最大深度为10(如果成本相同,转运节点最少)
  21. MATCH path = (n:AGENCY) -[*..10]->(m:AGENCY)
  22. WHERE n.name = "北京市昌平区定泗路" AND m.name = "上海市浦东新区南汇"
  23. UNWIND relationships(path) AS r
  24. WITH sum(r.cost) AS cost, path
  25. RETURN path ORDER BY cost ASC, LENGTH(path) ASC LIMIT 1
  26. //UNWIND是将列表数据展开操作
  27. //sum()是聚合统计函数,类似还有:avg()、max()、min()等

 2.6.分页查询

  1. //分页查询网点,按照bid正序排序,每页查询2条数据,第一页
  2. MATCH (n:AGENCY)
  3. RETURN n ORDER BY n.bid ASC SKIP 0 LIMIT 2
  4. //第二页
  5. MATCH (n:AGENCY)
  6. RETURN n ORDER BY n.bid ASC SKIP 2 LIMIT 2
  7. //……

2.7.更新数据

 更新数据是使用SET语句进行标签、属性的更新。SET操作是幂等性的。

  1. // 更新/设置 属性
  2. MATCH (n:AGENCY {name:"北京市昌平区新龙城"})
  3. SET n.address = "龙跃苑四区3号楼底商101号"
  4. RETURN n
  5. //通过remove移除属性
  6. MATCH (n:AGENCY {name:"北京市昌平区新龙城"}) REMOVE n.address RETURN n
  7. //没有address属性的增加属性
  8. MATCH (n:AGENCY) WHERE n.address IS NULL SET n.address = "暂无地址" RETURN n

2.8.删除数据

删除数据通过DELETE、DETACH DELETE完成。其中DELETE不能删除有关系的节点,删除关系就需要DETACH DELETE了。 

  1. //删除节点
  2. MATCH (n:AGENCY {name:"航头营业部"}) DELETE n
  3. //有关系的节点是不能直接删除的
  4. MATCH (n:AGENCY {name:"北京市昌平区新龙城"}) DELETE n
  5. //删除节点和关系
  6. MATCH (n:AGENCY {name:"北京市昌平区新龙城"}) DETACH DELETE n
  7. //删除所有节点和关系,慎用!
  8. MATCH (n) DETACH DELETE n

2.9.索引

 在Neo4j中同样也支持索引,对字段做索引可以提升查询速度。

  1. //创建索引语法:
  2. //OPTIONS子句指定索引提供程序和配置。
  3. CREATE [TEXT] INDEX [index_name] [IF NOT EXISTS]
  4. FOR (n:LabelName)
  5. ON (n.propertyName)
  6. [OPTIONS "{" option: value[, ...] "}"]
  7. //示例:
  8. CREATE TEXT INDEX agency_index_bid IF NOT EXISTS FOR (n:AGENCY) ON (n.bid)
  9. //删除索引语法:
  10. DROP INDEX index_name
  11. //示例:
  12. DROP INDEX agency_index_bid

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/429718
推荐阅读
相关标签
  

闽ICP备14008679号