neo4j查询语句 查询语句
图数据库已经越来越被人们熟知,同时也在许多企业中得到了应用,但是由于市面上没有统一的图查询语言标准,所以有部分开发者对于不同图数据库的用法存在着疑问 。因此本文作者对市面上主流的几款图数据库进行了一番分析,并以查询操作为例进行深入介绍 。
文章的开头我们先来看下什么是图数据库,根据维基百科的定义:图数据库是使用图结构进行语义查询的数据库,它使用节点、边和属性来表示和存储数据 。
虽然和关系型数据库存储的结构不同(关系型数据库为表结构,图数据库为图结构),但不计各自的性能问题,关系型数据库可以通过递归查询或者组合其他 SQL 语句(Join)完成图查询语言查询节点关系操作 。得益于 1987 年 SQL 成为国际标准化组织(ISO)标准,关系型数据库行业得到了很好的发展 。同 60、70 年代的关系型数据库类似,图数据库这个领域的查询语言目前也没有统一标准,虽然 19 年 9 月经过国际 SQL 标准委员会投票表决,决定将图查询语言(Graph Query Language)纳为一种新的数据库查询语言,但 GQL 的制定仍需要一段时间 。
文章插图
文章插图
文章插图
文章插图
文章插图
删除数据复制代码
# nGQLnebula> DELETE VERTEX hash("prometheus");# Gremlingremlin> g.V(prometheus).drop();# Cyphercypher> MATCH (n:character {name:"prometheus"}) DETACH DELETE n 这里,我们可以看到大家的删除关键词都是类似的:Delete 和 Drop,不过这里需要注意的是上面术语篇中提过 nGQL 中删除操作对应单词有 Delete 和 Drop ,在 nGQL 中 Delete 一般用于点边,Drop 用于 Schema 删除,这点和 SQL 的设计思路是一样的 。
更新数据复制代码
# nGQLnebula> UPDATE VERTEX hash("jesus") SET character.type = 'titan';# Gremlingremlin> g.V(jesus).property('age', 6000);==>v<32># Cyphercypher> MATCH (n:character {name:"jesus"}) SET n.type = 'titan';可以看到 Cypher 和 nGQL 都使用 SET 关键词来设置点对应的类型值,只不过 nGQL 中多了 UPDATE 关键词来标识操作,Gremlin 的操作和查看点操作类似,只不过增加了变更 property 值操作,这里我们注意到的是,Cypher 中常见的一个关键词便是 MATCH,顾名思义,它是一个查询关键词,它会去选择匹配对应条件下的点边,再进行下一步操作 。
查看数据复制代码
# nGQLnebula> FETCH PROP ON character hash("saturn");===================================================| character.name | character.age | character.type |===================================================| saturn| 10000| titan|---------------------------------------------------# Gremlingremlin> g.V(saturn).valueMap();==>,age:<10000>># Cyphercypher> MATCH (n:character {name:"saturn"}) RETURN properties(n)╒════════════════════════════════════════════╕│"properties(n)"│╞════════════════════════════════════════════╡│{"name":"saturn","type":"titan","age":10000}│└────────────────────────────────────────────┘在查看数据这块,Gremlin 通过调取 valueMap() 获得对应的属性值,而 Cypher 正如上面更新数据所说,依旧是 MATCH 关键词来进行对应的匹配查询再通过 RETURN 返回对应的数值,而 nGQL 则对 saturn 进行 hash 运算得到对应 VID 之后去获取对应 VID 的属性值 。
查询 hercules 的父亲复制代码
# nGQLnebula>LOOKUP ON character WHERE character.name == 'hercules' | \-> GO FROM $-.VertexID OVER father YIELD $$.character.name;=====================| $$.character.name |=====================| jupiter|---------------------# Gremlingremlin> g.V().hasLabel('character').has('name','hercules').out('father').values('name');==>jupiter# Cyphercypher> MATCH (src:character{name:"hercules"})-<:father>->(dst:character) RETURN dst.name╒══════════╕│"dst.name"│╞══════════╡│"jupiter" │└──────────┘查询父亲,其实是一个查询关系 / 边的操作,这里不做赘述,上面插入边的时候简单介绍了 Gremlin、Cypher、nGQL 这三种图数据库是各自用来标识边的关键词和操作符是什么 。
查询 hercules 的祖父复制代码
# nGQLnebula> LOOKUP ON character WHERE character.name == 'hercules' | \-> GO 2 STEPS FROM $-.VertexID OVER father YIELD $$.character.name;=====================| $$.character.name |=====================| saturn|---------------------# Gremlingremlin> g.V().hasLabel('character').has('name','hercules').out('father').out('father').values('name');==>saturn# Cyphercypher> MATCH (src:character{name:"hercules"})-<:father*2>->(dst:character) RETURN dst.name╒══════════╕│"dst.name"│╞══════════╡│"saturn"│└──────────┘查询祖父,其实是一个查询对应点的两跳关系,即:父亲的父亲,我们可以看到 Gremlin 使用了两次 out() 来表示为祖父,而 nGQL 这里使用了 |(Pipe 管道) 的概念,用于子查询 。在两跳关系处理上,上面说到 Gremlin 是用了 2 次 out(),而 Cypher、nGQL 则引入了 step 数的概念,分别对应到查询语句的 GO 2 STEP 和 <:father *2>,相对来说 Cypher、nGQL 这样书写更优雅 。
查询年龄大于 100 的人物复制代码
# nGQLnebula> LOOKUP ON character WHERE character.age > 100 YIELD character.name, character.age;=========================================================| VertexID| character.name | character.age |=========================================================| 6761447489613431910| pluto| 4000|---------------------------------------------------------| -5860788569139907963 | neptune| 4500|---------------------------------------------------------| 4863977009196259577| jupiter| 5000|---------------------------------------------------------| -4316810810681305233 | saturn| 10000|---------------------------------------------------------# Gremlingremlin> g.V().hasLabel('character').has('age',gt(100)).values('name');==>saturn==>jupiter==>neptune==>pluto# Cyphercypher> MATCH (src:character) WHERE src.age > 100 RETURN src.name╒═══════════╕│"src.name" │╞═══════════╡│"saturn" │├───────────┤│ "jupiter" │├───────────┤│ "neptune" ││───────────││"pluto"│└───────────┘这个是一个典型的查询语句,找寻符合特定条件的点并返回结果,在 Cypher 和 nGQL 中用 WHRER 进行条件判断,而 Gremlin 延续了它的“编程风”用 gt(100) 表示年大于龄 100 的这个筛选条件,延伸下 Gremlin 中 eq() 则表示等于这个查询条件 。
从一起居住的人物中排除 pluto 本人复制代码
# nGQLnebula>GO FROM hash("pluto") OVER lives YIELD lives._dst AS place | GO FROM $-.place OVER lives REVERSELY WHERE \$$.character.name != "pluto" YIELD $$.character.name AS cohabitants;===============| cohabitants |===============| cerberus|---------------# Gremlingremlin> g.V(pluto).out('lives').in('lives').where(is(neq(pluto))).values('name');==>cerberus# Cyphercypher> MATCH (src:character{name:"pluto"})-<:lives>->()<-<:lives>-(dst:character) RETURN dst.name╒══════════╕│"dst.name"│╞══════════╡│"cerberus"│└──────────┘这是一个沿指定点 Pluto 反向查询指定边(居住)的操作,在反向查询中,Gremlin 使用了 in 来表示反向关系,而 Cypher 则更直观的将指向箭头反向变成 <- 来表示反向关系,nGQL 则用关键词 REVERSELY 来标识反向关系 。
Pluto 的兄弟们居住在哪复制代码
# which brother lives in which place?## nGQLnebula> GO FROM hash("pluto") OVER brother YIELD brother._dst AS god | \GO FROM $-.god OVER lives YIELD $^.character.name AS Brother, $$.location.name AS Habitations;=========================| Brother | Habitations |=========================| jupiter | sky|-------------------------| neptune | sea|-------------------------## Gremlingremlin> g.V(pluto).out('brother').as('god').out('lives').as('place').select('god','place').by('name');==>
【neo4j查询语句 查询语句】最后,本文只是对 Gremlin、Cypher、nGQL 等 3 个图查询语言进行了简单的介绍,更复杂的语法将在本系列的后续文章中继续,欢迎在论坛留言交流 。
推荐阅读
- 移动网上查询通话详单 联通网上查询通话详单
- 从小米官网哪里查询手机真伪
- 网络密码忘记了怎么找回密码 服务密码忘了怎么查询
- 联想电脑如何查询出厂日期 电脑如何查询出厂日期
- 中国电信宽带号码 中国电信宽带账号查询
- 网站快速收录 网站收录查询
- 小米手机防伪码查询 小米防伪码查询网站
- 小米笔记本查询真伪官网 小米查询真伪官网
- 怎么激活苹果手机 苹果手机激活查询
- 苹果质保期查询在哪 苹果质保期查询