gremlin3.3.3 第三部分 - 1-图的遍历(2)

gremlin3.3.3 第三部分 - 1-图的遍历(2)_第1张图片

3.3.3

图的遍历

gremlin3.3.3 第三部分 - 1-图的遍历(2)_第2张图片

Barrier(屏障) Step

barrier()-step
(barrier)将原有管道延迟转换为大容量同步管道。这一步骤可在以下场景使用:

  • 当需要在某个步骤执行之前,需要之前的Step全部执行完毕方可执行时,可用barrier() (例如排序)

  • 当通过barrier() “延缓”Step时,可能会促使重复元素的“批量优化”(即优化)。

 gremlin\> g.V().sideEffect{
     println "first: \${it}"}.sideEffect{
     println
    "second: \${it}"}.iterate()

-   first: v[1]

-   second: v[1]

-   first: v[2]

-   second: v[2]

-   first: v[3]

-   second: v[3]

-   first: v[4]

-   second: v[4]

-   first: v[5]

-   second: v[5]

-   first: v[6]

-   second: v[6]

-   gremlin\> g.V().sideEffect{
     println "first:
    \${
     it}"}.barrier().sideEffect{println "second: \${
     it}"}.iterate()

-   first: v[1]

-   first: v[2]

-   first: v[3]

-   first: v[4]

-   first: v[5]

-   first: v[6]

-   second: v[1]

-   second: v[2]

-   second: v[3]

-   second: v[4]

-   second: v[5]

-   second: v[6]

“批量优化”背后的理论很简单。如果顶点1有一百万次遍历,那么就不需要计算一百万个both()计算。相反,使用traverser
.bulk()将这100万遍历表示为单个遍历等同于这100万遍历再执行一次both()。下面的例子展示了利用Grateful
Dead图,在大的Graph上作批量优化例子。

>   gremlin\> graph = TinkerGraph.open()

>   ==\>tinkergraph[vertices:0 edges:0]

>   gremlin\> graph.io(graphml()).readGraph('data/grateful-dead.xml')

>   gremlin\> g = graph.traversal().withoutStrategies(LazyBarrierStrategy)

>   ==\>graphtraversalsource[tinkergraph[vertices:808 edges:8049], standard]

>   gremlin\> clockWithResult(1){
     g.V().both().both().both().count().next()}

>   ==\>10339.5204

>   ==\>126653966

>   gremlin\> clockWithResult(1){
     g.V().repeat(both()).times(3).count().next()}
>   \\

>   ==\>29.239853

>   ==\>126653966

>   gremlin\>
>   clockWithResult(1){
     g.V().both().barrier().both().barrier().both().barrier().count().next()}

>   ==\>14.841833

>   ==\>126653966
  1. 用LazyBarrierStrategy(批量优化)显式地删除。

  2. 每个遍历器处理非大量的遍历。

  3. 每个进入repeat()的遍历器都将其递归增涨。

  4. 不处理隐式遍历的大容量遍历。

如果barrier()提供了一个整数参数,那么barrier在将聚合遍历释放到下一个步骤之前,它的barrier中只包含n个惟一性的遍历器。这在前面提到的批量优化场景中非常有用,还可以减少内存不足异常的风险。

LazyBarrierStrategy将barrier()步骤插入到适当的遍历中,以获得“批量优化”。

>   gremlin\> graph = TinkerGraph.open()

>   ==\>tinkergraph[vertices:0 edges:0]

>   gremlin\> graph.io(graphml()).readGraph('data/grateful-dead.xml')

>   gremlin\> g = graph.traversal() \\

>   ==\>graphtraversalsource[tinkergraph[vertices:808 edges:8049], standard]

>   gremlin\> clockWithResult(1){
     g.V().both().both().both().count().next()}

>   ==\>17.782709

>   ==\>126653966

>   gremlin\> g.V().both().both().both().count().iterate().toString()
>   /==\>[TinkerGraphStep(vertex,**[]**), VertexStep(BOTH,vertex),
>   NoOpBarrierStep(2500), VertexStep(BOTH,vertex), NoOpBarrierStep(2500),
>   VertexStep(BOTH,edge), CountGlobalStep, NoneStep]
  1. LazyBarrierStrategy是默认策略,因此不需要显式激活。

  2. 激活LazyBarrierStrategy后,barrier()步骤将自动插入适当的位置。

其他用法

barrier(), barrier(Consumer), barrier(int)

By(聚合选项) Step

by()-step不是一个实际的步骤,而是一个类似as()和option()的“步进调制器”。如果一个步骤能够接受遍历、函数、比较器等,那么by()就是添加它们的方法。一般的模式是step().by()…by()。有些步骤只能接受一次
by()步骤,而其他步骤可以接受任意数量。

>   gremlin\> g.V().group().by(bothE().count())

>   ==\>[1:[v[2],v[5],v[6]],3:[v[1],v[3],v[4]]]

>   gremlin\> g.V().group().by(bothE().count()).by('name') \\

>   ==\>[1:[vadas,ripple,peter],3:[marko,lop,josh]]

>   gremlin\> g.V().group().by(bothE().count()).by(count())

>   ==\>[1:3,3:3]
  1. by(outE().count())将根据元素的边计数(遍历之后)对其进行分组。

  2. by(‘name’)将按名称处理分组的元素(元素属性投影)。

  3. by(count())将计算每个组中的元素数量(遍历)。

下面的Step均支持by()操作。使用方式也遵循 step-by-step的逻辑,同时,在文档的其他部分中也有描述。

  • dedup():根据 by()的结果而去重。

  • cyclicPath():通过by()过滤遍历器的循环路径。

  • simplePath():通过by()过滤遍历器的简单路径。

  • sample():使用by()-的返回值进行采样。

  • where():给定by()-调制的测试结果,确定谓词。

  • groupCount():对 by()过滤的group keys进行计数。

  • group():根据by()-过滤分组。

  • order():根据by()-过滤排序。

  • path():根据by()-过滤遍历器的路径。

  • project():根据by()-不同的过滤条件获取当前对象map的结果。

  • select():根据by()-过滤路径元素。

  • tree():根据by()-过滤获得一个Tree遍历器。

  • aggregate():存储合并集合中by()-过滤的属性值。

  • store():存储合并集合中by()-过滤的对象值。

其他用法

by(), by(Comparator), by(Function,Comparator), by(Function), by(Order), by(String), by(String,Comparator), by(T), by(Traversal), by(Traversal,Comparator), T, Order

Cap(自引用) Step

cap()-step (barrier)
是自引用遍历。如果提供了多个key,则sideEffect 的结果会是 Map 类型。

>   gremlin\> g.V().groupCount('a').by(label).cap('a') \\

>   ==\>[software:2,person:4]

>   gremlin\>
>   g.V().groupCount('a').by(label).groupCount('b').by(outE().count()).cap('a','b')

>   ==\>[a:[software:2,person:4],b:[0:3,1:1,2:1,3:1]]
  1. 根据顶点的label对顶点进行分组和计数。以a为标记此次结果,即按label计数的分组。

  2. 与语句1相同,但也会产生标记为“b”的结果,它根据输出边的数量对顶点进行分组。

其他用法

cap(String,String…​)

Choose(选择) Step

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XGCG71vf-1596635336877)(media/19c1f989d7154444f5a93b328ef6ea84.png)]

choose ()-step
(branch)将当前遍历提供路由选择器。使用choose(),可以实现if/then/else语义以及更复杂的选择方式。

>   gremlin\> g.V().hasLabel('person').

>   choose(values('age').is(lte(30)),

>   \_\_.in(),

>   \_\_.out()).values('name') \\

>   ==\>marko

>   ==\>ripple

>   ==\>lop

>   ==\>lop

>   gremlin\> g.V().hasLabel('person').

>   choose(values('age')).

>   option(27, \_\_.in()).

>   option(32, \_\_.out()).values('name') \\

>   ==\>marko

>   ==\>ripple

>   ==\>lop
  1. 如果遍历查找label=person的元素,如果age<=30,那么执行in,否则执行out,最终取name。

  2. 同样的查找,只是在判断时,27才执行In,
    32执行Out。意思是找到person属性顶点中27的入边名称和32的出边名称

Choose是三元式,如果没有提供“false”-分支,则默认用If /then实现。

gremlin> g.V().choose(hasLabel(‘person’), out(‘created’)).values(‘name’) ==>lop ==>lop ==>ripple ==>lop ==>ripple ==>lop gremlin> g.V().choose(hasLabel(‘person’), out(‘created’), identity()).values(‘name’) ==>lop ==>lop ==>ripple ==>lop ==>ripple ==>lop
  1. 如果有person标签则找到他们出边created的顶点name,否则输出自己的name。

  2. 与1 等价。

注意,choose()和options 可以任意组合多个,而且可以将匿名遍历作为其选择函数。

>   gremlin\> g.V().hasLabel('person').

>   choose(values('name')).

>   option('marko', values('age')).

>   option('josh', values('name')).

>   option('vadas', valueMap()).

>   option('peter', label())

>   ==\>29

>   ==\>[name:[vadas],age:[27]]

>   ==\>josh

>   ==\>person

choose()-step可以Pick.none提供未匹配的场景。对于任何与指定选项不匹配的内容,将采用none-选项。

>   gremlin\> g.V().hasLabel('person').

>   choose(values('name')).

>   option('marko', values('age')).

>   option(none, values('name'))

>   ==\>29

>   ==\>vadas

>   ==\>josh

>   ==\>peter

其他用法

choose(Function), choose(Predicate,Traversal), choose(Predicate,Traversal,Traversal), choose(Traversal,Traversal), choose(Traversal,Traversal,Traversal), choose(Traversal)

Coalesce(合并) Step

coalesce()步骤按遍历顺序将多个traversal 合并,并返回至少产生一个元素的第一次遍历。

>   gremlin\> g.V(1).coalesce(outE('knows'),
>   outE('created')).inV().path().by('name').by(label)

>   ==\>[marko,knows,vadas]

>   ==\>[marko,knows,josh]

>   gremlin\> g.V(1).coalesce(outE('created'),
>   outE('knows')).inV().path().by('name').by(label)

>   ==\>[marko,created,lop]

>   gremlin\> g.V(1).property('nickname', 'okram')

>   ==\>v[1]

>   gremlin\> g.V().hasLabel('person').coalesce(values('nickname'),
>   values('name'))

>   ==\>okram

>   ==\>vadas

>   ==\>josh

>   ==\>peter

其他用法

coalesce(Traversal…​)

Coin(硬币) Step

,使用coin()-step (filter) 作为随机筛选遍历器。coin
使用double类型参数,结果会有所偏差。

>   gremlin\> g.V().coin(0.5)

>   ==\>v[1]

>   ==\>v[2]

>   ==\>v[5]

>   ==\>v[6]

>   gremlin\> g.V().coin(0.0)

>   gremlin\> g.V().coin(1.0)

>   ==\>v[1]

>   ==\>v[2]

>   ==\>v[3]

>   ==\>v[4]

>   ==\>v[5]

>   ==\>v[6]

其他用法

coin(double)

Constant (常量) Step

constant()-step
(map)可以将一个常数值作为一个遍历器,在choose()-step或coalesce()-step中比较有用。

>   gremlin\> g.V().choose(hasLabel('person'),

>   values('name'),

>   constant('inhuman'))

>   ==\>marko

>   ==\>vadas

>   ==\>inhuman

>   ==\>josh

>   ==\>inhuman

>   ==\>peter

>   gremlin\> g.V().coalesce(

>   hasLabel('person').values('name'),

>   constant('inhuman')) \\

>   ==\>marko

>   ==\>vadas

>   ==\>inhuman

>   ==\>josh

>   ==\>inhuman

>   ==\>peter
  1. Label=person的顶点显示name属性,不是的则显示inhuman。

  2. 与表述1相同 coalesce的写法。

其他用法

constant(Object)

Count (计算) Step

gremlin3.3.3 第三部分 - 1-图的遍历(2)_第3张图片

count()-step (map)对流中所表示的遍历器的总数进行计数(即批量计数)。

>   gremlin\> g.V().count()

>   ==\>6

>   gremlin\> g.V().hasLabel('person').count()

>   ==\>4

>   gremlin\> g.V().hasLabel('person').outE('created').count().path() \\

>   ==\>[4]

>   gremlin\> g.V().hasLabel('person').outE('created').count().map {
     it.get() \*
>   10}.path()

>   ==\>[4,40]
  1. count()-步骤是一个 reducing
    barrier 步骤,意思是说所有以前的遍历器都被折叠到一个新的遍历器中。

  2. 由count()发出的遍历路径从count()开始。

IMPORTANT count(local)对当前本地对象(而不是遍历流中的对象)进行计数。这适用于 Collection - - Map类型的对象。对于任何其他对象,返回的计数为1。

其他用法

count(), count(Scope), Scope

CyclicPath (环路) Step

gremlin3.3.3 第三部分 - 1-图的遍历(2)_第4张图片

每个遍历器通过遍历图来维护其历史——即path。如果遍历器重复它的过程很重要,那么应该使用cycle
()-path
(filter)。这个Step分析遍历器到目前为止的路径,如果有任何重复,遍历器将在遍历计算中过滤掉。如果需要非循环的处理,请参阅simplePath()。

>   gremlin\> g.V(1).both().both()

>   ==\>v[1]

>   ==\>v[4]

>   ==\>v[6]

>   ==\>v[1]

>   ==\>v[5]

>   ==\>v[3]

>   ==\>v[1]

>   gremlin\> g.V(1).both().both().cyclicPath()

>   ==\>v[1]

>   ==\>v[1]

>   ==\>v[1]

>   gremlin\> g.V(1).both().both().cyclicPath().path()

>   ==\>[v[1],v[3],v[1]]

>   ==\>[v[1],v[2],v[1]]

>   ==\>[v[1],v[4],v[1]]

>   gremlin\> g.V(1).as('a').out('created').as('b').

>   in('created').as('c').

>   cyclicPath().

>   path()

>   ==\>[v[1],v[3],v[1]]

>   gremlin\> g.V(1).as('a').out('created').as('b').

>   in('created').as('c').

>   cyclicPath().from('a').to('b').

>   path()

其他用法

cyclicPath
()

Dedup(去重) Step

使用dedup()-step
(filter),可以从遍历流中删除重复看到的对象。注意,如果遍历器的容量大于1,则在遍历之前将其设置为1。

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

>   ==\>java

>   ==\>java

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

>   ==\>java

>   gremlin\> g.V(1).repeat(bothE('created').dedup().otherV()).emit().path() \\

>   ==\>[v[1],e[9][1-created-\>3],v[3]]

>   ==\>[v[1],e[9][1-created-\>3],v[3],e[11][4-created-\>3],v[4]]

>   ==\>[v[1],e[9][1-created-\>3],v[3],e[12][6-created-\>3],v[6]]

>   ==\>[v[1],e[9][1-created-\>3],v[3],e[11][4-created-\>3],v[4],e[10][4-created-\>5],v[5]]
  1. 遍历所有属性= created的边,但不会返回重复。

如果dedup()和By-step 结合使用,则在确定它是否被看到之前对该对象进行相应的处理。

>   gremlin\> g.V().valueMap(true, 'name')

>   ==\>[id:1,name:[marko],label:person]

>   ==\>[id:2,name:[vadas],label:person]

>   ==\>[id:3,name:[lop],label:software]

>   ==\>[id:4,name:[josh],label:person]

>   ==\>[id:5,name:[ripple],label:software]

>   ==\>[id:6,name:[peter],label:person]

>   gremlin\> g.V().dedup().by(label).values('name')

>   ==\>marko

>   ==\>lop

最后,如果提供了字符串数组dedup(),那么它将确保重复数据删除不是针对当前Step的遍历器对象,而是针对遍历器的路径历史(即dedup之前的语句)。

>   gremlin\>
>   g.V().as('a').out('created').as('b').in('created').as('c').select('a','b','c')

>   ==\>[a:v[1],b:v[3],c:v[1]]

>   ==\>[a:v[1],b:v[3],c:v[4]]

>   ==\>[a:v[1],b:v[3],c:v[6]]

>   ==\>[a:v[4],b:v[5],c:v[4]]

>   ==\>[a:v[4],b:v[3],c:v[1]]

>   ==\>[a:v[4],b:v[3],c:v[4]]

>   ==\>[a:v[4],b:v[3],c:v[6]]

>   ==\>[a:v[6],b:v[3],c:v[1]]

>   ==\>[a:v[6],b:v[3],c:v[4]]

>   ==\>[a:v[6],b:v[3],c:v[6]]

>   gremlin\>
>   g.V().as('a').out('created').as('b').in('created').as('c').dedup('a','b').select('a','b','c')

>   ==\>[a:v[1],b:v[3],c:v[1]]

>   ==\>[a:v[4],b:v[5],c:v[4]]

>   ==\>[a:v[4],b:v[3],c:v[1]]

>   ==\>[a:v[6],b:v[3],c:v[1]]
  1. 如果a和b组合中结果已经出现过,那么遍历器将去重。

其他用法

dedup(Scope,String…​), dedup(String…​), Scope

Drop (释放/删除) Step

drop()步骤(filter/sideEffect)模式均可)用于从图中删除元素和属性(即remove)。它是一个过滤器步骤,因为它不会产出对象。

>   gremlin\> g.V().outE().drop()

>   gremlin\> g.E()

>   gremlin\> g.V().properties('name').drop()

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

>   ==\>[age:[29]]

>   ==\>[age:[27]]

>   ==\>[lang:[java]]

>   ==\>[age:[32]]

>   ==\>[lang:[java]]

>   ==\>[age:[35]]

>   gremlin\> g.V().drop()

>   gremlin\> g.V()

其他用法

drop()

Emit(发出) Step

emit-step不是一个实际意义上的步骤,而是repeat()的一个步骤调节器(在那里可以找到emit()的更多文档)。

其他用法

emit(), emit(Predicate), emit(Traversal)

Explain (解释) Step

explain()-step
(terminal)将返回一个TraversalExplanation。遍历解释详细说明了给定已注册的遍历策略如何编译遍历(在explain()之前)。TraversalExplanation 的toString()返回三列。第一列是应用的遍历策略。第二列是遍历策略类别:[D]生态化,[O]ptimization,
[P]rovider optimization, [F]inalization,
[V]erification。第三列是遍历公布的策略应用程序的状态。最后的遍历是结果的执行计划。

>   gremlin\>
>   g.V().hasLabel('person').outE().identity().inV().count().is(gt(5)).explain()

>   ==\>Traversal Explanation

>   =====================================================================================================================================================================================================

>   Original Traversal [GraphStep(vertex,**[]**), HasStep([\~label.eq(person)]),
>   VertexStep(OUT,edge), IdentityStep, EdgeVertexStep(IN), CountGlobalStep,
>   IsStep(gt(5))]

>   ConnectiveStrategy [D] [GraphStep(vertex,**[]**),
>   HasStep([\~label.eq(person)]), VertexStep(OUT,edge), IdentityStep,
>   EdgeVertexStep(IN), CountGlobalStep, IsStep(gt(5))]

>   MatchPredicateStrategy [O] [GraphStep(vertex,**[]**),
>   HasStep([\~label.eq(person)]), VertexStep(OUT,edge), IdentityStep,
>   EdgeVertexStep(IN), CountGlobalStep, IsStep(gt(5))]

>   FilterRankingStrategy [O] [GraphStep(vertex,**[]**),
>   HasStep([\~label.eq(person)]), VertexStep(OUT,edge), IdentityStep,
>   EdgeVertexStep(IN), CountGlobalStep, IsStep(gt(5))]

>   InlineFilterStrategy [O] [GraphStep(vertex,**[]**),
>   HasStep([\~label.eq(person)]), VertexStep(OUT,edge), IdentityStep,
>   EdgeVertexStep(IN), CountGlobalStep, IsStep(gt(5))]

>   IncidentToAdjacentStrategy [O] [GraphStep(vertex,**[]**),
>   HasStep([\~label.eq(person)]), VertexStep(OUT,edge), IdentityStep,
>   EdgeVertexStep(IN), CountGlobalStep, IsStep(gt(5))]

>   RepeatUnrollStrategy [O] [GraphStep(vertex,**[]**),
>   HasStep([\~label.eq(person)]), VertexStep(OUT,edge), IdentityStep,
>   EdgeVertexStep(IN), CountGlobalStep, IsStep(gt(5))]

>   PathRetractionStrategy [O] [GraphStep(vertex,**[]**),
>   HasStep([\~label.eq(person)]), VertexStep(OUT,edge), IdentityStep,
>   EdgeVertexStep(IN), CountGlobalStep, IsStep(gt(5))]

>   CountStrategy [O] [GraphStep(vertex,**[]**), HasStep([\~label.eq(person)]),
>   VertexStep(OUT,edge), IdentityStep, EdgeVertexStep(IN),
>   RangeGlobalStep(0,6), CountGlobalStep, IsStep(gt(5))]

>   AdjacentToIncidentStrategy [O] [GraphStep(vertex,**[]**),
>   HasStep([\~label.eq(person)]), VertexStep(OUT,edge), IdentityStep,
>   EdgeVertexStep(IN), RangeGlobalStep(0,6), CountGlobalStep, IsStep(gt(5))]

>   LazyBarrierStrategy [O] [GraphStep(vertex,**[]**),
>   HasStep([\~label.eq(person)]), VertexStep(OUT,edge), IdentityStep,
>   EdgeVertexStep(IN), RangeGlobalStep(0,6), CountGlobalStep, IsStep(gt(5))]

>   TinkerGraphCountStrategy [P] [GraphStep(vertex,**[]**),
>   HasStep([\~label.eq(person)]), VertexStep(OUT,edge), IdentityStep,
>   EdgeVertexStep(IN), RangeGlobalStep(0,6), CountGlobalStep, IsStep(gt(5))]

>   TinkerGraphStepStrategy [P] [TinkerGraphStep(vertex,[\~label.eq(person)]),
>   VertexStep(OUT,edge), IdentityStep, EdgeVertexStep(IN),
>   RangeGlobalStep(0,6), CountGlobalStep, IsStep(gt(5))]

>   ProfileStrategy [F] [TinkerGraphStep(vertex,[\~label.eq(person)]),
>   VertexStep(OUT,edge), IdentityStep, EdgeVertexStep(IN),
>   RangeGlobalStep(0,6), CountGlobalStep, IsStep(gt(5))]

>   StandardVerificationStrategy [V]
>   [TinkerGraphStep(vertex,[\~label.eq(person)]), VertexStep(OUT,edge),
>   IdentityStep, EdgeVertexStep(IN), RangeGlobalStep(0,6), CountGlobalStep,
>   IsStep(gt(5))]

>   Final Traversal [TinkerGraphStep(vertex,[\~label.eq(person)]),
>   VertexStep(OUT,edge), IdentityStep, EdgeVertexStep(IN),
>   RangeGlobalStep(0,6), CountGlobalStep, IsStep(gt(5))]

有关遍历分析信息,请参见profile()步骤。

Fold (折叠) Step

在某些情况下,遍历流需要一个“barrier”来聚合所有对象并发出一个计算,该计算是聚合的一个函数。fold()-step
(map)就是其中的一个实例。请参阅展开()—步骤了解相反的功能。

>   gremlin\> g.V(1).out('knows').values('name')

>   ==\>vadas

>   ==\>josh

>   gremlin\> g.V(1).out('knows').values('name').fold() \\

>   ==\>[vadas,josh]

>   gremlin\> g.V(1).out('knows').values('name').fold().next().getClass()

>   ==\>**class java**.util.ArrayList

>   gremlin\> g.V(1).out('knows').values('name').fold(0) {
     a,b -\> a +
>   b.length()} \\

>   ==\>9

>   gremlin\> g.V().values('age').fold(0) {
     a,b -\> a + b}

>   ==\>123

>   gremlin\> g.V().values('age').fold(0, sum)

>   ==\>123

>   gremlin\> g.V().values('age').sum() \\

>   ==\>123
  1. 无参的fold()将把所有对象聚合到一个列表中,然后发出这个列表。

  2. 对返回的列表类型进行验证。

  3. fold()可以提供两个参数—一个种子值和一个reduce的bi方法(“vadas”是5个字符+“josh”是4个字符)。

  4. 图中这些人的总年龄是多少?

  5. 功能同上,但是使用内置的bi方法。

  6. 功能同上,使用sum()步骤。

其他用法

fold(), fold(Object,BiFunction)

From (从) Step

from()-step不是一个实际的步骤,而是一个类似as()和by()的“Step调节器”。如果一个步骤能够接受遍历或字符串,则使用from()来指代要添加的对象。一般模式是step().from()。参考to()。

支持from()-的步骤有:
simplePath(), cyclicPath(), path(),
and addE()

其他用法

from(String), from(Traversal), from(Vertex)

Graph (图谱) Step

V()步骤通常用于开始graph遍历,但也可以在遍历的中间使用。

>   gremlin\> g.V().has('name', within('marko', 'vadas', 'josh')).as('person').

>   V().has('name', within('lop', 'ripple')).addE('uses').from('person')

>   ==\>e[13][1-uses-\>3]

>   ==\>e[14][1-uses-\>5]

>   ==\>e[15][2-uses-\>3]

>   ==\>e[16][2-uses-\>5]

>   ==\>e[17][4-uses-\>3]

>   ==\>e[18][4-uses-\>5]
NOTE 是否mid-traversal V()是否使用索引,取决于 a)是否存在合适的索引 b)是否graph 系统具备索引功能。
>   gremlin\> g.V().has('name', within('marko', 'vadas', 'josh')).as('person').

>   V().has('name', within('lop',
>   'ripple')).addE('uses').from('person').toString() \\

>   ==\>[GraphStep(vertex,**[]**), HasStep([name.within([marko, vadas,
>   josh])])\@[person], GraphStep(vertex,**[]**), HasStep([name.within([lop,
>   ripple])]), AddEdgeStep({
     \~from=[[SelectOneStep(last,person)]],
>   label=[uses]})]

>   gremlin\> g.V().has('name', within('marko', 'vadas', 'josh')).as('person').

>   V().has('name', within('lop',
>   'ripple')).addE('uses').from('person').iterate().toString() \\

>   ==\>[TinkerGraphStep(vertex,[name.within([marko, vadas, josh])])\@[person],
>   TinkerGraphStep(vertex,[name.within([lop, ripple])]),
>   AddEdgeStep({
     \~from=[[SelectOneStep(last,person)]], label=[uses]}),
>   NoneStep]
  1. 通常,V()步骤将遍历所有顶点。然而,graph策略可以折叠 HasContainer’s into a
    `GraphStep ,以允许索引查找。

  2. 通过检查迭代遍历的toString()输出,可以很容易地确定图形系统提供程序是否支持中间遍历V()索引查找。如果has 条件被折叠到V()步骤中,将使用索引(如果存在)。

其他用法

V(Object…​)

你可能感兴趣的:(JanusGraph)