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