图数据库入门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') | 从各个年龄的人中选出一个代表 |
更多推荐
已为社区贡献1条内容
所有评论(0)