图数据库入门1——简介与Gremlin基本语法
图数据库入门——Gremlin图数据库与Gremlin基本语法最最基础的语法查询节点查询边图数据库与Gremlin图数据库是非关系型数据库(noSQL)的一种,利用实体间的对应关系来存储数据。Gremlin语言是图数据库最主流的查询语言。其地位就相当于关系型数据库的SQL。本文将以hugeGraph图数据库为例来介绍Gremlin语言的基本语法和相关操作。基本语法最最基础的语法查询节点命令效果g.
·
图数据库与Gremlin
- 图数据库是非关系型数据库(noSQL)的一种,利用实体间的对应关系来存储数据。
- Gremlin语言是图数据库最主流的查询语言。其地位就相当于关系型数据库的SQL。
本文将以hugeGraph图数据库为例来介绍Gremlin语言的基本语法和相关操作。
基本语法
最最基础的语法
tips:
- Gremlin中的 " 和 ’ 是等价的
查询节点
命令 | 效果 |
---|---|
g.V() |
查询所有节点信息,g表示整张图,一切的查询都是以图开始 |
g.V("1:abc@qq.com") |
根据节点信息查询相应节点,引号中的1表示节点的类型所对应的序号,通常是在groovy文件中添加的第一种节点类型;abc@qq.com是要查询的节点的主键 |
g.V("1:abc@qq.com","2:100") |
多条查询可以使用逗号隔开 |
g.V().id() |
查询所有节点对应的id,返回属性是一个列表 |
g.V().label() |
查询所有节点对应的label,返回属性是一个列表 |
g.V().properties() |
查询所有结点的属性 |
g.V().properties("name") |
查询所有结点的name属性,若没有则跳过 |
g.V().properties().key() |
查询所有节点属性的key值 |
g.V().properties().value() |
查询所有节点属性的value值 |
g.V().valueMap() |
查询所有节点的属性,返回值是一对对键值对 |
g.V().values() |
查询所有节点的value值,等同于g.V().properties().value() |
查询边
命令 | 效果 |
---|---|
g.E() |
查询所有边的信息 |
b.E("S1:abc@qq.com>1>>S2:100") |
根据边的类型,其实就是边的id查询相应边 |
g.E().label() |
查询所有边对应的label,返回属性是一个列表 |
g.E().properties() |
查询所有边的属性 |
g.E().properties("name") |
查询所有边的name属性,若没有则跳过 |
g.E().properties().key() |
查询所有边属性的key值 |
g.E().properties().value() |
查询所有边属性的value值 |
g.E().valueMap() |
查询所有边的属性,返回值是一对对键值对 |
g.E().values() |
查询所有边的value值,等同于g.E().properties().value() |
边的遍历
命令 | 效果 |
---|---|
g.V().in() |
先查询所有的节点,再找到每个节点的父节点。注意:图数据库不会为其结果自动去重! |
g.V().out() |
先查询所有节点,再找到每个节点的子节点 |
g.V("1:abc@qq.com").out() |
找到abc@qq.com节点的子节点 |
g.V("1:abc@qq.com").out("buy") |
找到abc@qq.com节点的子节点,且要求该子节点与abc@qq.com之间的边的label是buy |
g.V("1:abc@qq.com").both() |
查询和其相邻的节点,即in()和out()的并集 |
g.V("1:abc@qq.com").outE() |
找到以abc@qq.com为起点的边 |
g.V("1:abc@qq.com").inE() |
找到以abc@qq.com为终点的边 |
g.V("1:abc@qq.com").outE("buy") |
找到以abc@qq.com为起点的,label为buy的边 |
g.V("1:abc@qq.com").bothE() |
找到和abc@qq.com相连的所有边 |
g.E().inV() |
先找到所有边,再找每条边的终点。 注意:inV()表示终点,outV()表示起点 通常g.V().inE().outV() = g.V().in() |
g.E().outV() |
先找到所有边,再找每条边的起点。 注意:inV()表示终点,outV()表示起点 通常g.V().outE().inV() = g.V().out() |
g.E().bothV() |
找到所有有边的顶点 |
g.V("1:abc@qq.com").inE().otherV() |
找到以abc@qq.com为终点的边的另一端顶点,即等价于in() |
has条件过滤
在HugeGraph中,按property的值查询之前,应该对property建立索引,否则将无法查到结果并引发异常。(有两个例外,Vertex的PrimaryKeys和Edge的SortKeys,具体参见HugeGraph官网)
- 使用has系列命令之前,需要在schema中添加索引(不包含主键索引),如下所示,表示为person类型的节点添加address的索引。
graph.schema().indexLabel('person_address').onV('person').by('address').secondary().ifNotExist().create()
命令 | 效果 |
---|---|
g.V().hasLabel("person") |
查询拥有person标签的节点 |
g.V().hasLabel("person","email") |
查询拥有person或email标签的节点。 注意:gremlin中的逗号表示或运算 |
g.V().hasId("1") |
查询id为1的节点 |
g.V().has("name","paul") |
查询name字段为paul的节点 |
g.V().has("person","name","paul") |
查询label为person且name字段为paul的节点 |
g.V().has("age",gt(30)) |
查询age字段大于30的节点 |
g.V().properties().haskey("name") |
查询所有属性中有name字段的节点 注意:当后端是Cassandra时,可用g.V().haskey(“name”) |
g.V().properties().hasValue("Beijing") |
查询所有属性值为Beijing的节点 注意:当后端是Cassandra时,可用g.V().hasValue(“Beijing”) |
g.V().has("name") |
查询有name字段的所有节点 |
g.V().hasNot("name") |
查询没有name字段的所有节点 |
设置查询的数量限制
命令 | 效果 |
---|---|
g.V().count() |
所有结点的数量 |
g.V().hasLabel("name").count() |
所有label为name的节点的数量 |
g.V().properties().count() |
查询所有节点的属性总数 |
g.V().hasLabel("name").range(0, -1) |
查询所有节点中的第一个到最后一个,和python的range语法相同 |
g.V().limit(9) |
查询前9个节点 |
g.E().tail(3) |
查询后3条边 |
g.V().hasLabel("name").skip(2) |
跳过前两条数据,相当于g.V().hasLabel(“name”).range(2, -1) |
path查询路径
命令 | 效果 |
---|---|
g.V("1:abc@qq.com").both().path() |
查询和abc@qq.com相邻的所有节点,随后输出其路径,注意只包含节点信息 |
g.V("1:abc@qq.com").bothE().otherV().path() |
查询和abc@qq.com相邻的所有节点,随后输出其路径,注意包含节点和边的信息 |
g.V("1:abc@qq.com").bothE().otherV().path().by("name") |
查询路径,并使用name属性来代替显示出的字段 |
g.V("1:abc@qq.com").both().both().simplePath().path() |
过滤环路 |
g.V("1:abc@qq.com").both().both().cyclicPath().path() |
只要环路 |
循环语句
命令 | 效果 |
---|---|
g.V("2:100").repeat(out()).times(2) |
相当于g.V("2:100").out().out() |
g.V("1:abc@qq.com").repeat(out()).until(has("money","100")).path() |
查询一条从abc@qq.com出发的路径,终点是money为100的节点 |
g.V("1:abc@qq.com").repeat(out()).emit().path() |
找到所有abc@qq.com可达的节点,emit()能够记录中间过程,其内可以添加条件 |
g.V("1:abc@qq.com").repeat(out()) .until(has("money","100")).emit().path() |
查询一条从abc@qq.com出发的路径,终点是money为100的节点,期间记录所有中间节点 |
g.V("2:100").repeat(out()).until(loops().is(3)) |
查询所有三度可达节点 |
g.V("2:100").repeat(out()).until(loops().is(3)).and(has("name")) |
查询所有三度可达节点,并且其含有name字段 |
排序
命令 | 效果 |
---|---|
g.V().values('name').order() |
默认按照升序排序 |
g.V().values('name').order().by(decr) |
指定降序 |
g.V().values('name').order().by(incr) |
指定升序 |
g.V().values('name').order().by(shuffle) |
随机排序 |
g.V().hasLabel('person').order().by('age') |
按照某一字段排序 |
g.V().hasLabel('person').order().by('age', incr).values('age') |
将person类型的顶点按照age升序排列,并获取age属性 |
分组与去重
命令 | 效果 |
---|---|
g.V().hasLabel("person").group() |
分组 |
g.V().hasLabel("person").group().by('age') |
按年龄分组 |
g.V().hasLabel("person").group().by('age').by(count()) |
按年龄分组,按数量显示 |
g.V().group().by(label).by(count()) |
按标签将节点分组,并输出数量 |
g.V().hasLabel('person').groupCount() |
分组计数 |
g.V().hasLabel('person').groupCount().by('age') |
按年龄分组计数 |
g.V().both().hasLabel('person').dedup() |
同顶点去重 |
g.V().hasLabel('person').values('age').dedup() |
按年龄去重 |
g.V().hasLabel('person').dedup().by('age') |
从各个年龄的人中选出一个代表 |
更多推荐
所有评论(0)