首发于 ShinningCoCo
10. Gremlin 基础操作

10. Gremlin 基础操作

1. 基础操作

在HugeGraph-Hubble中Gremlin分析功能中运行脚本,需要先选择当前访问的图。

在Gremlin Console中运行脚本需要做如下设置:

graph=hugegraph //使用hugegraph图

g=graph.traversal() //获取hugegrap图的遍历源:g 代表整个hugegraph图

遍历结果验证:可以使用Hubble的图形展示功能,分析结果是否正确。

1.1. 遍历基本操作

【Gremlin Steps】V()、E()、id()、label()、properties()、valueMap()、values()、value()

以下操作基于TinkerGraph Modern图和TinkerPop关系图来进行。

ü V():查询顶点,一般作为图查询的第1步

ü E():查询边,一般作为图查询的第1步

ü id():获取顶点、边的id。

ü label():获取顶点、边的label。

ü properties():获取顶点、边的属性。

ü valueMap():获取顶点、边的属性

ü values(): 获取属性值,等同于 properties().value()

ü value():获取属性值

1.1.1. Step V:查询图中所有顶点

n Step V():查询所有顶点,一般作为图查询的第1步,一般需要后带过滤条件。尤其数据量大时,不建议使用不带过滤条件的g.V()查询。

gremlin> g.V()

==>[id:rui,label:person,type:vertex,properties:[name:Rui Zhao,age:29,addr:Beijing,weight:2.0]]

==>[id:bowen,label:person,type:vertex,properties:[name:Bowen Li,age:25,addr:Guiyang.Guizhou,weight:1.0]]

==>[id:okram,label:person,type:vertex,properties:[name:Marko A. Rodriguez,age:29,addr:Santa Fe, New Mexico,weight:1.0]]

==>[id:dalaro,label:person,type:vertex,properties:[name:Dan LaRocque ,age:0,addr:,weight:1.0]]

==>[id:javeme,label:person,type:vertex,properties:[name:Jermy Li,age:29,addr:Beijing,weight:1.0]]

==>[id:linary,label:person,type:vertex,properties:[name:Linary Li,age:28,addr:Wuhan. Hubei,weight:1.0]]

==>[id:zhoney,label:person,type:vertex,properties:[name:Zhoney Zhang,age:29,addr:Beijing,weight:1.0]]

==>[id:2:Titan,label:software,type:vertex,properties:[name:Titan,lang:java,tag:Graph Database,weight:1.0]]

==>[id:3:Gremlin,label:language,type:vertex,properties:[name:Gremlin,lang:groovy/python/javascript,weight:1.0]]

==>[id:shangrila,label:person,type:vertex,properties:[name:Shangrila Xie,age:33,addr:Guangzhou,weight:3.0]]

==>[id:spmallette,label:person,type:vertex,properties:[name:Stephen Mallette,age:0,addr:,weight:1.0]]

==>[id:2:HugeGraph,label:software,type:vertex,properties:[name:HugeGraph,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:TinkerPop,label:software,type:vertex,properties:[name:TinkerPop,lang:java,tag:Graph computing framework,weight:1.0]]

==>[id:mbroecheler,label:person,type:vertex,properties:[name:Matthias Broecheler,age:29,addr:San Francisco,weight:1.0]]

==>[id:2:CirroGraph,label:software,type:vertex,properties:[name:CirroGraph,lang:java,tag:Graph Database,weight:3.0]]

==>[id:2:TinkerGraph,label:software,type:vertex,properties:[name:TinkerGraph,lang:java,tag:In-memory property graph,weight:1.0]]

gremlin>

【注意】

1. 输出点的详细信息:ID、点label、类型、属性集合。

2. 查询顶点,一般作为图查询的第1步

1.1.2. Step E:查询图中所有边

n Step E():查询所有顶点,一般作为图查询的第1步,一般需要后带过滤条件。尤其数据量大时,不建议使用不带过滤条件的g.E()查询。

gremlin> g.E()

gremlin> g.E()

==>[id:Srui>2>>S2:CirroGraph,label:created,type:edge,outV:rui,outVLabel:person,inV:2:CirroGraph,inVLabel:software,properties:[weight:2.0]]

==>[id:Sbowen>2>>S2:CirroGraph,label:created,type:edge,outV:bowen,outVLabel:person,inV:2:CirroGraph,inVLabel:software,properties:[weight:1.0]]

==>[id:Sokram>1>>Sspmallette,label:knows,type:edge,outV:okram,outVLabel:person,inV:spmallette,inVLabel:person,properties:[weight:1.0]]

==>[id:Sokram>2>>S2:Titan,label:created,type:edge,outV:okram,outVLabel:person,inV:2:Titan,inVLabel:software,properties:[weight:1.0]]

==>[id:Sokram>2>>S2:TinkerPop,label:created,type:edge,outV:okram,outVLabel:person,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:Sdalaro>1>>Smbroecheler,label:knows,type:edge,outV:dalaro,outVLabel:person,inV:mbroecheler,inVLabel:person,properties:[weight:1.0]]

==>[id:Sdalaro>2>>S2:Titan,label:created,type:edge,outV:dalaro,outVLabel:person,inV:2:Titan,inVLabel:software,properties:[weight:1.0]]

==>[id:Sjaveme>1>>Slinary,label:knows,type:edge,outV:javeme,outVLabel:person,inV:linary,inVLabel:person,properties:[weight:1.0]]

==>[id:Sjaveme>1>>Szhoney,label:knows,type:edge,outV:javeme,outVLabel:person,inV:zhoney,inVLabel:person,properties:[weight:1.0]]

==>[id:Sjaveme>2>>S2:HugeGraph,label:created,type:edge,outV:javeme,outVLabel:person,inV:2:HugeGraph,inVLabel:software,properties:[weight:1.0]]

==>[id:Slinary>2>>S2:HugeGraph,label:created,type:edge,outV:linary,outVLabel:person,inV:2:HugeGraph,inVLabel:software,properties:[weight:1.0]]

==>[id:Szhoney>2>>S2:HugeGraph,label:created,type:edge,outV:zhoney,outVLabel:person,inV:2:HugeGraph,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:Titan>5>>S2:TinkerPop,label:implements,type:edge,outV:2:Titan,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:Titan>6>>S3:Gremlin,label:supports,type:edge,outV:2:Titan,outVLabel:software,inV:3:Gremlin,inVLabel:language,properties:[weight:1.0]]

==>[id:Sshangrila>1>>Srui,label:knows,type:edge,outV:shangrila,outVLabel:person,inV:rui,inVLabel:person,properties:[weight:1.0]]

==>[id:Sshangrila>1>>Sbowen,label:knows,type:edge,outV:shangrila,outVLabel:person,inV:bowen,inVLabel:person,properties:[weight:1.0]]

==>[id:Sshangrila>2>>S2:CirroGraph,label:created,type:edge,outV:shangrila,outVLabel:person,inV:2:CirroGraph,inVLabel:software,properties:[weight:3.0]]

==>[id:Sspmallette>2>>S2:TinkerPop,label:created,type:edge,outV:spmallette,outVLabel:person,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:HugeGraph>5>>S2:TinkerPop,label:implements,type:edge,outV:2:HugeGraph,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:HugeGraph>6>>S3:Gremlin,label:supports,type:edge,outV:2:HugeGraph,outVLabel:software,inV:3:Gremlin,inVLabel:language,properties:[weight:1.0]]

==>[id:S2:TinkerPop>3>>S2:TinkerGraph,label:contains,type:edge,outV:2:TinkerPop,outVLabel:software,inV:2:TinkerGraph,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:TinkerPop>4>>S3:Gremlin,label:define,type:edge,outV:2:TinkerPop,outVLabel:software,inV:3:Gremlin,inVLabel:language,properties:[weight:1.0]]

==>[id:Smbroecheler>2>>S2:Titan,label:created,type:edge,outV:mbroecheler,outVLabel:person,inV:2:Titan,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:CirroGraph>5>>S2:TinkerPop,label:implements,type:edge,outV:2:CirroGraph,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:CirroGraph>6>>S3:Gremlin,label:supports,type:edge,outV:2:CirroGraph,outVLabel:software,inV:3:Gremlin,inVLabel:language,properties:[weight:1.0]]

==>[id:S2:TinkerGraph>6>>S3:Gremlin,label:supports,type:edge,outV:2:TinkerGraph,outVLabel:software,inV:3:Gremlin,inVLabel:language,properties:[weight:1.0]]

gremlin>

【注意】

1. 输出边的详细信息:ID、边label、类型、源点(outV)、源点label、目标点(inV)、目标点label、属性集合。

2. 边的ID(系统自动生成的):Sokram>1>>Sspmallette 从顶点Sokram到顶点Sspmallette的边

3. 查询边,一般作为图查询的第1步

1.1.3. V(ids)/E(ids): 根据id查询顶点、边

// 根据id查询顶点

gremlin> g.V('3:Gremlin', '2:TinkerPop')

==>[id:3:Gremlin,label:language,type:vertex,properties:[name:Gremlin,lang:groovy/python/javascript,weight:1.0]]

==>[id:2:TinkerPop,label:software,type:vertex,properties:[name:TinkerPop,lang:java,tag:Graph computing framework,weight:1.0]]

//查询支持Gremlin语言的所有图数据库

gremlin> g.V('3:Gremlin').in('supports')

==>[id:2:Titan,label:software,type:vertex,properties:[name:Titan,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:HugeGraph,label:software,type:vertex,properties:[name:HugeGraph,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:TinkerGraph,label:software,type:vertex,properties:[name:TinkerGraph,lang:java,tag:In-memory property graph,weight:1.0]]

// 根据id查询边

gremlin> g.E('S2:TinkerPop>4>>S3:Gremlin')

==>[id:S2:TinkerPop>4>>S3:Gremlin,label:define,type:edge,outV:2:TinkerPop,outVLabel:software,inV:3:Gremlin,inVLabel:language,properties:[weight:1.0]]

1.1.4. Step id:获取顶点、边的id

n Step id():查询顶点的ID。

// 查询所有顶点的id:注意fold()步骤使用后结果输出

gremlin> g.V().id()

==>rui

==>bowen

==>okram

==>dalaro

==>javeme

==>linary

==>zhoney

==>2:Titan

==>3:Gremlin

==>shangrila

==>spmallette

==>2:HugeGraph

==>2:TinkerPop

==>mbroecheler

==>2:CirroGraph

==>2:TinkerGraph

gremlin>

gremlin> g.V().id().fold()

==>[rui,bowen,okram,dalaro,javeme,linary,zhoney,2:Titan,3:Gremlin,shangrila,spmallette,2:HugeGraph,2:TinkerPop,mbroecheler,2:CirroGraph,2:TinkerGraph]

gremlin>

// 查询所有边的id:注意fold()步骤使用后结果输出

gremlin> g.E().id()

gremlin> g.E().id()

==>Srui>2>>S2:CirroGraph

==>Sbowen>2>>S2:CirroGraph

==>Sokram>1>>Sspmallette

==>Sokram>2>>S2:Titan

==>Sokram>2>>S2:TinkerPop

==>Sdalaro>1>>Smbroecheler

==>Sdalaro>2>>S2:Titan

==>Sjaveme>1>>Slinary

==>Sjaveme>1>>Szhoney

==>Sjaveme>2>>S2:HugeGraph

==>Slinary>2>>S2:HugeGraph

==>Szhoney>2>>S2:HugeGraph

==>S2:Titan>5>>S2:TinkerPop

==>S2:Titan>6>>S3:Gremlin

==>Sshangrila>1>>Srui

==>Sshangrila>1>>Sbowen

==>Sshangrila>2>>S2:CirroGraph

==>Sspmallette>2>>S2:TinkerPop

==>S2:HugeGraph>5>>S2:TinkerPop

==>S2:HugeGraph>6>>S3:Gremlin

==>S2:TinkerPop>3>>S2:TinkerGraph

==>S2:TinkerPop>4>>S3:Gremlin

==>Smbroecheler>2>>S2:Titan

==>S2:CirroGraph>5>>S2:TinkerPop

==>S2:CirroGraph>6>>S3:Gremlin

==>S2:TinkerGraph>6>>S3:Gremlin

gremlin> g.E().id().fold()

==>[Sokram>1>>Sspmallette,Sokram>2>>S2:Titan,Sokram>2>>S2:TinkerPop,Sdalaro>1>>Smbroecheler,Sdalaro>2>>S2:Titan,Sjaveme>1>>Slinary,Sjaveme>1>>Szhoney,Sjaveme>2>>S2:HugeGraph,Slinary>2>>S2:HugeGraph,Szhoney>2>>S2:HugeGraph,S2:Titan>5>>S2:TinkerPop,S2:Titan>6>>S3:Gremlin,Sspmallette>2>>S2:TinkerPop,S2:HugeGraph>5>>S2:TinkerPop,S2:HugeGraph>6>>S3:Gremlin,S2:TinkerPop>3>>S2:TinkerGraph,S2:TinkerPop>4>>S3:Gremlin,Smbroecheler>2>>S2:Titan,S2:TinkerGraph>6>>S3:Gremlin]

gremlin>

【注意】

1. Gremlin Step是作用在上一步产生的结果集上,如果上一步的结果是多个元素,那么这里id()将返回多个元素的id。

2. fold()是把前一步产生的结果以集合的形式折叠起来。

1.1.5. Step label:获取顶点、边的label

n Step label():查询顶点/边的标签(label)。

// 查询所有顶点的label

gremlin> g.V().label()

==>person

==>person

==>person

==>person

==>person

==>person

==>person

==>software

==>language

==>person

==>person

==>software

==>software

==>person

==>software

==>software

gremlin>

gremlin> g.V().label().dedup()

==>person

==>software

==>language

gremlin> g.V().label().dedup().fold()

==>[person,software,language]

gremlin> g.E().label().dedup().fold()

==>[knows,created,implements,supports,contains,define]

【注意】

1. dedup() 去重,不去重的话返回结果是g.V()返回的结果数量,即每个顶点都输出其label

1.1.6. Step valueMap: 获取顶点、边的属性

n valueMap():获取顶点、边的属性

// 查询所有顶点的所有属性值

gremlin> g.V().valueMap().with(WithOptions.tokens)

gremlin> g.V().valueMap(true)

==>[id:rui,label:person,name:[Rui Zhao],age:[29],addr:[Beijing],weight:[2.0]]

==>[id:bowen,label:person,name:[Bowen Li],age:[25],addr:[Guiyang.Guizhou],weight:[1.0]]

==>[id:okram,label:person,name:[Marko A. Rodriguez],age:[29],addr:[Santa Fe, New Mexico],weight:[1.0]]

==>[id:dalaro,label:person,name:[Dan LaRocque ],age:[0],addr:[],weight:[1.0]]

==>[id:javeme,label:person,name:[Jermy Li],age:[29],addr:[Beijing],weight:[1.0]]

==>[id:linary,label:person,name:[Linary Li],age:[28],addr:[Wuhan. Hubei],weight:[1.0]]

==>[id:zhoney,label:person,name:[Zhoney Zhang],age:[29],addr:[Beijing],weight:[1.0]]

==>[id:2:Titan,label:software,name:[Titan],lang:[java],tag:[Graph Database],weight:[1.0]]

==>[id:3:Gremlin,label:language,name:[Gremlin],lang:[groovy/python/javascript],weight:[1.0]]

==>[id:shangrila,label:person,name:[Shangrila Xie],age:[33],addr:[Guangzhou],weight:[3.0]]

==>[id:spmallette,label:person,name:[Stephen Mallette],age:[0],addr:[],weight:[1.0]]

==>[id:2:HugeGraph,label:software,name:[HugeGraph],lang:[java],tag:[Graph Database],weight:[1.0]]

==>[id:2:TinkerPop,label:software,name:[TinkerPop],lang:[java],tag:[Graph computing framework],weight:[1.0]]

==>[id:mbroecheler,label:person,name:[Matthias Broecheler],age:[29],addr:[San Francisco],weight:[1.0]]

==>[id:2:CirroGraph,label:software,name:[CirroGraph],lang:[java],tag:[Graph Database],weight:[3.0]]

==>[id:2:TinkerGraph,label:software,name:[TinkerGraph],lang:[java],tag:[In-memory property graph],weight:[1.0]]

gremlin>

注意:

ü g.V().valueMap(true)与g.V().valueMap()的区别是:是否返回顶点的id和label, 前者返回顶点的id和label

ü g.V().valueMap().with(WithOptions.tokens)与g.V().valueMap(true)返回结果一样,推荐使用这种方式

ü 每个顶点返回一行,所有属性在一个集合里

ü 不返回属性的ID值

ü 类似的,通过g.E().valueMap()查询所有边的属性

// 查询所有顶点的name属性值

gremlin> g.V().valueMap('name')

==>[name:[Marko A. Rodriguez]]

==>[name:[Dan LaRocque ]]

==>[name:[Jermy Li]]

==>[name:[Linary Li]]

==>[name:[Zhoney Zhang]]

==>[name:[Titan]]

==>[name:[Gremlin]]

==>[name:[Stephen Mallette]]

==>[name:[HugeGraph]]

==>[name:[TinkerPop]]

==>[name:[Matthias Broecheler]]

==>[name:[TinkerGraph]]

【注意】

建议使用valueMap(),高于3.4.3的Gremlin建议使用elememtMap().目前HugeGraph不能使用elememtMap()。

1.1.7. Step properties: 获取顶点、边的属性

n properties():获取顶点、边的属性(也包含值)

// 查询所有顶点的属性

g.V().properties()

类似的,通过g.E().properties()查询所有边的属性。

gremlin> g.V().properties()

==>[id:rui>name,value:Rui Zhao,label:name]

==>[id:rui>age,value:29,label:age]

==>[id:rui>addr,value:Beijing,label:addr]

==>[id:rui>weight,value:2.0,label:weight]

==>[id:bowen>name,value:Bowen Li,label:name]

==>[id:bowen>age,value:25,label:age]

==>[id:bowen>addr,value:Guiyang.Guizhou,label:addr]

==>[id:bowen>weight,value:1.0,label:weight]

【注意】

1. 按照每个顶点依次返回每个属性,即一个顶点的一个属性返回一行。一个顶点多个属性,每个属性都返回一行。

2. [id:rui>name,value:Rui Zhao,label:name]表面顶点rui的name属性,值是Rui Zhao。

返回结果去重:

gremlin> g.E().properties().dedup()

==>[key:weight,value:1.0]

==>[key:weight,value:1.0]

==>[key:weight,value:1.0]

n properties()还可以和 key()、value()搭配使用,以获取属性的名称或值。

// 查询所有顶点的属性名称(去重)

gremlin> g.V().properties().key().dedup()

==>name

==>age

==>addr

==>weight

==>lang

==>tag

// 查询所有顶点的属性值

g.V().values()效果等同与g.V().properties().value()

gremlin> g.V().properties().value()

gremlin> g.V().values()

// 查询具有“lang”属性的顶点:如果无“lang”属性的顶点将跳过

gremlin> g.V().properties('lang')

==>[id:2:Titan>lang,value:java,label:lang]

==>[id:3:Gremlin>lang,value:groovy/python/javascript,label:lang]

==>[id:2:HugeGraph>lang,value:java,label:lang]

==>[id:2:TinkerPop>lang,value:java,label:lang]

==>[id:2:CirroGraph>lang,value:java,label:lang]

==>[id:2:TinkerGraph>lang,value:java,label:lang]

// 查询具有 “lang”属性值的顶点

// 以下两种方式效果等同

g.V().properties('lang').value()

g.V().values('lang')

gremlin> g.V().values('lang')

==>java

==>groovy/python/javascript

==>java

==>java

==>java

1.2. Vertex Steps:顶点步骤

【Gremlin Steps】out()、in()、both()、outE()、inE()、bothE()、outV()、inV()、bothV()、otherV()

顶点步骤(flatMap)是 Gremlin 语言的基础。通过这些步骤,可以在图上“移动”--即遍历。Vertex Steps边遍历是指通过顶点来访问与其有关联边的邻接顶点,或者仅访问邻接边。基于顶点步骤的边遍历是图数据库与图计算的核心。

n 顶点为基准的Steps(如图中的顶点“4”):

out(label): 根据指定的EdgeLabel来访问顶点的OUT方向邻接点(可以是零个EdgeLabel,代表所有类型边;也可以一个或多个EdgeLabel,代表任意给定EdgeLabel的边,下同)

in(label): 根据指定的EdgeLabel来访问顶点的IN方向邻接点

both(label): 根据指定的EdgeLabel来访问顶点的双向邻接点

outE(label): 根据指定的EdgeLabel来访问顶点的OUT方向邻接边

inE(label): 根据指定的EdgeLabel来访问顶点的IN方向邻接边

bothE(label): 根据指定的EdgeLabel来访问顶点的双向邻接边

n 边为基准的Steps(如图中的边“knows”):

outV(): 访问边的出顶点,出顶点是指边的起始顶点

inV(): 访问边的入顶点,入顶点是指边的目标顶点,也就是箭头指向的顶点

bothV(): 访问边的双向顶点

otherV(): 访问边的伙伴顶点,即相对于基准顶点而言的另一端的顶点

通用解释:

① out(string...):根据给定的边标签来沿外向游走到相邻的那些顶点

② in(string...):根据给定的边标签来沿内向游走到相邻的那些顶点

③ both(string...):根据给定的边标签来双向游走到相邻的那些顶点

④ outE(string...):根据给定的边标签来沿外向游走到相邻的那些边

⑤ inE(string...):根据给定的边标签来沿内向游走到相邻的那些边

⑥ bothE(string...):根据给定的边标签来双向游走到相邻的那些边

⑦ outV():游走到外向顶点

⑧ inV():游走到内向顶点

⑨ bothV():游走双向定点

⑩ otherV():游走到边的其他顶点,这些顶点不包含此顶点从哪移动来的那些顶点

【注意】

在顶点步骤中,需要知道每个步骤结束后的结果集是什么:顶点还是边。

1.2.1. Step out:访问顶点的OUT方向邻接点

n Step out():访问顶点的外出(OUT)方向的邻接点,返回的是顶点集合。

示例1:一度、一跳

// 先查询图中所有的顶点,然后访问顶点的OUT方向邻接点

// 注意:out()的基准必须是顶点,返回的也是点

gremlin> g.V().out()

==>[id:spmallette,label:person,type:vertex,properties:[name:Stephen Mallette,age:0,addr:,weight:1.0]]

==>[id:2:Titan,label:software,type:vertex,properties:[name:Titan,lang:java,tag:Graph Database,weight:1.0]]

示例2:

// 访问某个顶点的OUT方向邻接点

// 注意'2:TinkerPop'是顶点的id,该id是插入顶点时自动生成的

gremlin> g.V('2:TinkerPop').out()

==>[id:2:TinkerGraph,label:software,type:vertex,properties:[name:TinkerGraph,lang:java,tag:In-memory property graph,weight:1.0]]

==>[id:3:Gremlin,label:language,type:vertex,properties:[name:Gremlin,lang:groovy/python/javascript,weight:1.0]]

gremlin>

示例3:

// 访问某个顶点'2:TinkerPop'的OUT方向邻接点

// 且限制仅“define”类型的边相连的顶点

gremlin> g.V('2:TinkerPop').out('define')

==>[id:3:Gremlin,label:language,type:vertex,properties:[name:Gremlin,lang:groovy/python/javascript,weight:1.0]]

增加一个边类型'contains'

gremlin> g.V('2:TinkerPop').out('define', 'contains')

==>[id:3:Gremlin,label:language,type:vertex,properties:[name:Gremlin,lang:groovy/python/javascript,weight:1.0]]

==>[id:2:TinkerGraph,label:software,type:vertex,properties:[name:TinkerGraph,lang:java,tag:In-memory property graph,weight:1.0]]

1.2.2. Step in:访问顶点的IN方向邻接点

n Step in():访问顶点的入(IN)方向的邻接点,返回的是顶点。

示例1:

// 访问某个顶点的IN方向邻接点,注意三种方式的返回值

gremlin> g.V('2:TinkerPop').in()

==>[id:okram,label:person,type:vertex,properties:[name:Marko A. Rodriguez,age:29,addr:Santa Fe, New Mexico,weight:1.0]]

==>[id:spmallette,label:person,type:vertex,properties:[name:Stephen Mallette,age:0,addr:,weight:1.0]]

==>[id:2:Titan,label:software,type:vertex,properties:[name:Titan,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:HugeGraph,label:software,type:vertex,properties:[name:HugeGraph,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:CirroGraph,label:software,type:vertex,properties:[name:CirroGraph,lang:java,tag:Graph Database,weight:3.0]]

gremlin> g.V('2:TinkerPop').in().values('name')

==>Marko A. Rodriguez

==>Stephen Mallette

==>Titan

==>HugeGraph

==>CirroGraph

gremlin> g.V('2:TinkerPop').in().valueMap('name')

==>[name:[Marko A. Rodriguez]]

==>[name:[Stephen Mallette]]

==>[name:[Titan]]

==>[name:[HugeGraph]]

==>[name:[CirroGraph]]

示例2:

// 访问某个顶点的IN方向邻接点,且限制了关联边的类型

gremlin> g.V('2:TinkerPop').in('implements')

==>[id:2:Titan,label:software,type:vertex,properties:[name:Titan,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:HugeGraph,label:software,type:vertex,properties:[name:HugeGraph,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:CirroGraph,label:software,type:vertex,properties:[name:CirroGraph,lang:java,tag:Graph Database,weight:3.0]]

1.2.3. Step both:访问顶点的双向邻接点

n Step both():访问顶点的双向的邻接点,返回的是顶点。

示例1:

// 访问某个顶点的双向邻接点

gremlin> g.V('2:TinkerPop').both()

==>[id:2:Titan,label:software,type:vertex,properties:[name:Titan,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:HugeGraph,label:software,type:vertex,properties:[name:HugeGraph,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:CirroGraph,label:software,type:vertex,properties:[name:CirroGraph,lang:java,tag:Graph Database,weight:3.0]]

gremlin> g.V('2:TinkerPop').both()

==>[id:2:TinkerGraph,label:software,type:vertex,properties:[name:TinkerGraph,lang:java,tag:In-memory property graph,weight:1.0]]

==>[id:3:Gremlin,label:language,type:vertex,properties:[name:Gremlin,lang:groovy/python/javascript,weight:1.0]]

==>[id:okram,label:person,type:vertex,properties:[name:Marko A. Rodriguez,age:29,addr:Santa Fe, New Mexico,weight:1.0]]

==>[id:spmallette,label:person,type:vertex,properties:[name:Stephen Mallette,age:0,addr:,weight:1.0]]

==>[id:2:Titan,label:software,type:vertex,properties:[name:Titan,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:HugeGraph,label:software,type:vertex,properties:[name:HugeGraph,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:CirroGraph,label:software,type:vertex,properties:[name:CirroGraph,lang:java,tag:Graph Database,weight:3.0]]

示例2:

// 访问某个顶点的双向邻接点,且限制了关联边的类型

gremlin> g.V('2:TinkerPop').both('implements', 'define')

==>[id:3:Gremlin,label:language,type:vertex,properties:[name:Gremlin,lang:groovy/python/javascript,weight:1.0]]

==>[id:2:Titan,label:software,type:vertex,properties:[name:Titan,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:HugeGraph,label:software,type:vertex,properties:[name:HugeGraph,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:CirroGraph,label:software,type:vertex,properties:[name:CirroGraph,lang:java,tag:Graph Database,weight:3.0]]

1.2.4. Step outE: 访问顶点的OUT方向邻接边

n Step outE():访问顶点的外出(OUT)方向的邻接边,返回的是边集合。

示例1:

// 访问某个顶点的OUT方向邻接边

gremlin> g.V('2:TinkerPop').outE()

==>[id:S2:TinkerPop>3>>S2:TinkerGraph,label:contains,type:edge,outV:2:TinkerPop,outVLabel:software,inV:2:TinkerGraph,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:TinkerPop>4>>S3:Gremlin,label:define,type:edge,outV:2:TinkerPop,outVLabel:software,inV:3:Gremlin,inVLabel:language,properties:[weight:1.0]]

gremlin>

示例2:

// 访问某个顶点的OUT方向邻接边

// 且限制了关联边的类型

gremlin> g.V('2:TinkerPop').outE('define')

==>[id:S2:TinkerPop>4>>S3:Gremlin,label:define,type:edge,outV:2:TinkerPop,outVLabel:software,inV:3:Gremlin,inVLabel:language,properties:[weight:1.0]]

gremlin>

1.2.5. Step inE: 访问顶点的IN方向邻接边

n Step inE():访问顶点的入方向的邻接边,返回的是边集合。

示例1:

// 访问某个顶点的IN方向邻接边:返回的是边

gremlin> g.V('2:TinkerPop').inE()

==>[id:S2:TinkerPop>4>>S3:Gremlin,label:define,type:edge,outV:2:TinkerPop,outVLabel:software,inV:3:Gremlin,inVLabel:language,properties:[weight:1.0]]

gremlin> g.V('2:TinkerPop').inE()

==>[id:Sokram>2>>S2:TinkerPop,label:created,type:edge,outV:okram,outVLabel:person,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:Sspmallette>2>>S2:TinkerPop,label:created,type:edge,outV:spmallette,outVLabel:person,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:Titan>5>>S2:TinkerPop,label:implements,type:edge,outV:2:Titan,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:HugeGraph>5>>S2:TinkerPop,label:implements,type:edge,outV:2:HugeGraph,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:CirroGraph>5>>S2:TinkerPop,label:implements,type:edge,outV:2:CirroGraph,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

示例2:

// 访问某个顶点的IN方向邻接边且限制了关联边的类型

gremlin> g.V('2:TinkerPop').inE('implements')

==>[id:S2:Titan>5>>S2:TinkerPop,label:implements,type:edge,outV:2:Titan,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:HugeGraph>5>>S2:TinkerPop,label:implements,type:edge,outV:2:HugeGraph,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:CirroGraph>5>>S2:TinkerPop,label:implements,type:edge,outV:2:CirroGraph,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

1.2.6. Step bothE: 访问顶点的双向邻接边

n Step bothE():访问顶点的双向的邻接边,返回的是边集合。

示例1:

// 访问某个顶点的双向邻接边

gremlin> g.V('2:TinkerPop').bothE()

==>[id:S2:TinkerPop>3>>S2:TinkerGraph,label:contains,type:edge,outV:2:TinkerPop,outVLabel:software,inV:2:TinkerGraph,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:TinkerPop>4>>S3:Gremlin,label:define,type:edge,outV:2:TinkerPop,outVLabel:software,inV:3:Gremlin,inVLabel:language,properties:[weight:1.0]]

==>[id:Sokram>2>>S2:TinkerPop,label:created,type:edge,outV:okram,outVLabel:person,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:Sspmallette>2>>S2:TinkerPop,label:created,type:edge,outV:spmallette,outVLabel:person,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:Titan>5>>S2:TinkerPop,label:implements,type:edge,outV:2:Titan,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:HugeGraph>5>>S2:TinkerPop,label:implements,type:edge,outV:2:HugeGraph,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:CirroGraph>5>>S2:TinkerPop,label:implements,type:edge,outV:2:CirroGraph,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

示例2:

// 访问某个顶点的双向邻接边且限制了关联边的类型

gremlin> g.V('2:TinkerPop').bothE('define', 'implements')

==>[id:S2:TinkerPop>4>>S3:Gremlin,label:define,type:edge,outV:2:TinkerPop,outVLabel:software,inV:3:Gremlin,inVLabel:language,properties:[weight:1.0]]

==>[id:S2:Titan>5>>S2:TinkerPop,label:implements,type:edge,outV:2:Titan,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:HugeGraph>5>>S2:TinkerPop,label:implements,type:edge,outV:2:HugeGraph,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

==>[id:S2:CirroGraph>5>>S2:TinkerPop,label:implements,type:edge,outV:2:CirroGraph,outVLabel:software,inV:2:TinkerPop,inVLabel:software,properties:[weight:1.0]]

1.2.7. Step outV: 访问边的出顶点(源顶点)

n Step outV():访问边的出顶点(源顶点,没有箭头的一端),返回的是顶点集合。输入是边,输出是点。

示例1:

// 访问某个顶点的IN邻接边,然后获取边的出顶点

gremlin> g.V('2:TinkerPop').inE().outV()

==>[id:okram,label:person,type:vertex,properties:[name:Marko A. Rodriguez,age:29,addr:Santa Fe, New Mexico,weight:1.0]]

==>[id:spmallette,label:person,type:vertex,properties:[name:Stephen Mallette,age:0,addr:,weight:1.0]]

==>[id:2:Titan,label:software,type:vertex,properties:[name:Titan,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:HugeGraph,label:software,type:vertex,properties:[name:HugeGraph,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:CirroGraph,label:software,type:vertex,properties:[name:CirroGraph,lang:java,tag:Graph Database,weight:3.0]]

【注意】

一般情况下,inE().outV()等价于in()

inE()表示所有入边(示例是5条),outV()表示这5条边每条的原顶点(边出发的顶点,没有箭头的那个顶点);in()表示所有的入边方向的顶点,显然inE().outV()等价于in()。

gremlin> g.V('2:TinkerPop').in()

==>[id:okram,label:person,type:vertex,properties:[name:Marko A. Rodriguez,age:29,addr:Santa Fe, New Mexico,weight:1.0]]

==>[id:spmallette,label:person,type:vertex,properties:[name:Stephen Mallette,age:0,addr:,weight:1.0]]

==>[id:2:Titan,label:software,type:vertex,properties:[name:Titan,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:HugeGraph,label:software,type:vertex,properties:[name:HugeGraph,lang:java,tag:Graph Database,weight:1.0]]

==>[id:2:CirroGraph,label:software,type:vertex,properties:[name:CirroGraph,lang:java,tag:Graph Database,weight:3.0]]

思考与动手:

gremlin> g.V('2:TinkerPop').outE().outV()

==>[id:2:TinkerPop,label:software,type:vertex,properties:[name:TinkerPop,lang:java,tag:Graph computing framework,weight:1.0]]

==>[id:2:TinkerPop,label:software,type:vertex,properties:[name:TinkerPop,lang:java,tag:Graph computing framework,weight:1.0]]

知道怎么解释这个结果吗?

g.V('2:TinkerPop').outE()返回的是顶点'2:TinkerPop'的出边(结果2条),这两条边的源顶点就是'2:TinkerPop'。g.V('2:TinkerPop').outE().outV()返回的就是这两条边的源顶点。

1.2.8. Step inV:访问边的入顶点(目标顶点)

n Step inV():访问边的入顶点(目标顶点或者边箭头指向的顶点),返回的是顶点集合。输入是边,输出是点。

示例1:

// 访问某个顶点的OUT邻接边,然后获取边的入顶点

gremlin> g.V('2:TinkerPop').outE().inV()

==>[id:2:TinkerGraph,label:software,type:vertex,properties:[name:TinkerGraph,lang:java,tag:In-memory property graph,weight:1.0]]

==>[id:3:Gremlin,label:language,type:vertex,properties:[name:Gremlin,lang:groovy/python/javascript,weight:1.0]]

【注意】

一般情况下,outE().inV()等价于out()

思考与动手:

gremlin> g.V('2:TinkerPop').inE().inV()

==>2:TinkerPop

==>2:TinkerPop

==>2:TinkerPop

==>2:TinkerPop

==>2:TinkerPop

1.2.9. Step bothV:访问边的双向顶点

n Step bothV():访问边的双向顶点,返回的是顶点集合。输入是边,输出是点。

示例1:

// 访问某个顶点的OUT邻接边,然后获取边的双向顶点,返回id值

gremlin> g.V('2:TinkerPop').outE().bothV().id()

==>2:TinkerPop

==>2:TinkerGraph

==>2:TinkerPop

==>3:Gremlin

【注意】

bothV()会把源顶点也一起返回,因此只要源顶点有多少条出边,结果集中就会出现多少次源顶点。

g.V('2:TinkerPop').as('s').outE().bothV().where(neq('s')).id()

==>2:TinkerGraph

==>3:Gremlin

1.2.10. Step otherV:访问边的对端顶点

n Step otherV():访问边的对端顶点,返回的是顶点集合。输入是边,输出是点。

示例1:

// 访问某个顶点的OUT邻接边,然后获取边的伙伴顶点

gremlin> g.V('2:TinkerPop').outE().otherV().id()

==>2:TinkerGraph

==>3:Gremlin

【注意】

一般情况下,outE().otherV()等价于out(),inE().otherV()等价于in()

以下语句是等效的:

g.V('2:TinkerPop').outE().otherV().id()

g.V('2:TinkerPop').out().id()

g.V('2:TinkerPop').outE().inV().id()

以下语句也是等效的:

g.V('2:TinkerPop').inE().otherV().id()

g.V('2:TinkerPop').inE().outV().id()

g.V('2:TinkerPop').in().id()

示例2:

// 访问某个顶点的双向邻接边,然后获取边的对端(伙伴)顶点

gremlin> g.V('2:TinkerPop').bothE().otherV().id()

==>2:TinkerGraph

==>3:Gremlin

==>okram

==>spmallette

==>2:Titan

==>2:HugeGraph

==>2:CirroGraph

【注意】

一般情况下,bothE().otherV()等价于both()

1.3. 综合运用

1.3.1. 多度查询

4度out()查询

// 1、通过id找到“javeme”作者顶点

// 2、通过out()访问其创建的软件

// 3、继续通过out()访问软件实现的框架

// 4、继续通过out()访问框架包含的软件

// 5、继续通过out()访问软件支持的语言

// 6、只返回ID

gremlin> g.V('javeme').out('created').out('implements').out('contains').out('supports').id()

==>3:Gremlin

1.3.2. 查询共同合作者

查询某个作者的共同作者

// 1、通过id找到“javeme”作者顶点

// 2、通过out()访问其创建的软件

// 3、通过in()访问软件的所有作者

// 4、只返回ID

gremlin> g.V('javeme').out('created').in('created').id()

==>javeme

==>linary

==>zhoney

如果返回结果不包含作者自己:

gremlin> g.V('javeme').as('s').out('created').in('created').where(neq('s')).id()

==>linary

==>zhoney

1.3.3. 查询支持Gremlin语言的软件的作者

查询支持Gremlin语言的软件的作者

// 1、通过id找到“Gremlin”语言顶点

// 2、通过in('supports')找到支持Gremlin的软件

// 3、继续通过in('created')访问软件的作者

// 4、只返回ID

gremlin> g.V('3:Gremlin').in('supports').in('created').id()

==>okram

==>dalaro

==>mbroecheler

==>javeme

==>linary

==>zhoney

==>rui

==>bowen

==>shangrila

发布于 2022-08-28 16:46

文章被以下专栏收录