TinkerPop中的遍歷:圖的遍歷步驟(2/3)


24 Group Step

有時,所運行的實際路徑或當前運行位置不是計算的最終輸出,而是遍歷的一些其他表示。group()步驟(map / sideEffect)是根據對象的某些功能組織對象的一個方法。
比如:

gremlin> g.V().group().by(label) 
==>[software:[v[3],v[5]],person:[v[1],v[2],v[4],v[6]]]
gremlin> g.V().group().by(label).by('name') 
==>[software:[lop,ripple],person:[marko,vadas,josh,peter]]
gremlin> g.V().group().by(label).by(count()) 
==>[software:2,person:4]

25 GroupCount Step

groupCount()分組統計,是(map/sideEffect)類型的步驟。

gremlin> g.V().hasLabel('person').values('age').groupCount() //
==>[32:1,35:1,27:1,29:1]
gremlin> g.V().hasLabel('person').groupCount().by('age') //
==>[32:1,35:1,27:1,29:1]

注意不能使用以下方式:
~~gremlin> g.V().hasLabel('person').by('age').groupCount()~~

26 Has Step

可以使用has()步驟(filter)根據其屬性來過濾頂點,邊和頂點屬性。 它有很多變體,包括:

has(key,value)
has(label, key, value)
has(key,predicate)
hasLabel(labels…)
hasId(ids…)
hasKey(keys…)
hasValue(values…)
has(key)
hasNot(key)
has(key, traversal)

27 Id Step

id()步驟(map)取一個Element並從中提取它的標識符。

gremlin> g.V().id() //所有頂底的ID
gremlin> g.V(1).outE().id() // 節點1發出的所有邊的ID
gremlin> g.V(1).properties().id() //節點1的所有屬性的ID

28 Inject Step

inject()步驟(sideEffect)使得可以將對象任意插入到遍歷流中。

gremlin> g.V(4).out().values('name')
==>ripple
==>lop
gremlin> g.V(4).out().values('name').inject('daniel')
==>daniel
==>ripple
==>lop
gremlin> g.V(4).out().values('name')
==>ripple
==>lop

29 Is Step

可以使用is()步驟(filter)來過濾標量值。

gremlin> g.V().values('age').is(32)
==>32
gremlin> g.V().values('age').is(lte(30))
==>29
==>27

30 Label Step

label()步驟(map)取一個Element並從中提取它的標簽。

gremlin> g.V().label() //所有頂點的標簽
gremlin> g.V(1).outE().label() //節點1出發的所有邊的標簽
gremlin> g.V(1).properties().label() //節點1的所有屬性的標簽

31 Key Step

key()步驟(map)取一個Property並從中提取該鍵。

gremlin> g.V(1).properties().key() //節點1的所有屬性的key
gremlin> g.V(1).properties().properties().key() //節點1的所有元屬性的key

32 Limit Step

limit() 步驟類似於range()步驟下限范圍設置為0的情況。

gremlin> g.V().limit(2)
==>v[1]
==>v[2]
gremlin> g.V().range(0, 2)
==>v[1]
==>v[2]

limit()也可以應用於 ,在這種情況下,它會對傳入的集合進行操作。

gremlin> g.V().valueMap().limit(local, 1) //對集合的操作
==>[name:[marko]]
==>[name:[vadas]]
==>[name:[lop]]
==>[name:[josh]]
==>[name:[ripple]]
==>[name:[peter]]
gremlin> g.V().valueMap().limit(1) //只取一個值
==>[name:[marko],age:[29]]

Note
注意,上述 local是靜態引入的Scope.local

33 Local Step

GraphTraversal對連續的對象流進行操作。在許多情況下,重要的是在該流中的單個元素上進行操作。要做這樣的對象局部遍歷計算,local()步驟(branch)因此而生。
比較以下遍歷:

gremlin> g.V().as('person').
               properties('location').order().by('startTime',incr).limit(2).value().as('location').
               select('person','location').by('name').by() 
==>[person:daniel,location:spremberg]
==>[person:stephen,location:centreville]
gremlin> g.V().as('person').
               local(properties('location').order().by('startTime',incr).limit(2)).value().as('location').
               select('person','location').by('name').by() 
==>[person:marko,location:san diego]
==>[person:marko,location:santa cruz]
==>[person:stephen,location:centreville]
==>[person:stephen,location:dulles]
==>[person:matthias,location:bremen]
==>[person:matthias,location:baltimore]
==>[person:daniel,location:spremberg]
==>[person:daniel,location:kaiserslautern]

上面的遍歷,根據最具歷史地理位置的開始時間,獲取前兩個人及其各自的位置。
下面的遍歷,對於每一個人來說,都有兩個歷史最悠久的地方。

上述遍歷使用Crew圖,該圖結構如下所示:
the crew graph

  • local()flatMap()
    local()步驟在功能上與flatMap()步驟非常相似,通常可能會使其混淆。 local()通過內部遍歷傳播遍歷器,而不會拆分/克隆它。因此,它在本地處理“全局遍歷”。
gremlin> g.V().both().barrier().flatMap(groupCount().by("name"))
==>[lop:1]
==>[lop:1]
==>[lop:1]
==>[vadas:1]
==>[josh:1]
==>[josh:1]
==>[josh:1]
==>[marko:1]
==>[marko:1]
==>[marko:1]
==>[peter:1]
==>[ripple:1]
gremlin> g.V().both().barrier().local(groupCount().by("name"))
==>[lop:3]
==>[vadas:1]
==>[josh:3]
==>[marko:3]
==>[peter:1]
==>[ripple:1]

34 Loops Step

loops()步驟(map)提取Traverser經過當前循環的次數。

35 Match Step

match()步驟(map)基於模式匹配的概念提供了一種更具聲明性的圖形查詢形式。
"Who created a project named 'lop' that was also created by someone who is 29 years old? Return the two creators."
match step

gremlin> g.V().match(
                 __.as('creators').out('created').has('name', 'lop').as('projects'), //1
                 __.as('projects').in('created').has('age', 29).as('cocreators')). //2
               select('creators','cocreators').by('name') //3
==>[creators:marko,cocreators:marko]
==>[creators:josh,cocreators:marko]
==>[creators:peter,cocreators:marko]

1: 找到創建了其他節點的節點,並將這些節點標記為“creators”,然后找出由“creators”創建的名為“lop”的節點,並將這些頂點匹配為“projects”。
2: 從這些“projects”頂點找出創建它們的節點,並過濾出其中年齡為29歲的節點,並將其記作“cocreators”。
3: 返回“creators”和“cocreators”的名稱。

使用where
Match通常與select()where()(在此呈現)結合使用。 where()步驟允許用戶進一步限制由match()提供的結果集。

如使用where去掉creators和cocreators相同的元素:

g.V().match(
                 __.as('creators').out('created').has('name', 'lop').as('projects'),
                 __.as('projects').in('created').has('age', 29).as('cocreators')).
                 where('creators',neq('cocreators')).
               select('creators','cocreators').by('name')

36 Max Step

max()步驟(map)對數字流進行操作,並確定流中最大的數字。

gremlin> g.V().values('age').max()
==>35

37 Mean Step

mean() 步驟(map)對數字流進行操作,並確定這些數字的平均值。

gremlin> g.V().values('age').mean()
==>30.75

38 Min Step

min()步驟(map)對數字流進行操作,並確定流中最小的數字。

gremlin> g.V().values('age').min()
==>27

39 Not Step

取反操作,屬於filter步驟。
示例:

gremlin> g.V().not(hasLabel('person')).valueMap() 
==>[name:[lop],lang:[java]]
==>[name:[ripple],lang:[java]] 

40 Option Step

branch() or choose()的選項。參考相應的遍歷步驟。

41 Optional Step

optional()步驟(map)在遍歷產生一個結果時返回相應結果,否則返回調用元素。
如下:

gremlin> g.V(1).optional(out('knows')) //1
==>v[2]
==>v[4]
gremlin> g.V(2).optional(out('knows')) //2
==>v[2]

1:當節點1具有向外的邊“knows”,則返回向外的邊指向的元素;
2:當節點2沒有向外的邊“knows”,則 返回節點2本身;

42 Or Step

or()步驟(filter)確保至少一個所提供的遍歷產生結果。
比如,只要符合具有發出“created”邊 或者 有進入“created”邊且進入邊的總數大於1 這兩個條件之一的遍歷結果就可以返回:

gremlin> g.V().or(
            __.outE('created'), //有發出“created”邊
            __.inE('created').count().is(gt(1))). //有進入“created”邊且進入邊的總數大於1
              values('name')
==>marko //符合第1個條件
==>lop  //符合第2個條件
==>josh //符合第1個條件
==>peter //符合第1個條件

需要注意的是,若遍歷對象流符合or()步驟中的多個條件,那么結果並不會重復。如下:

gremlin> g.V().or(
            __.outE('created'),
            __.hasLabel('person')).
              values('name')
==>marko
==>vadas
==>josh
==>peter      

都不符合提供的條件時,不返回結果。如下:

gremlin> g.V().or(
            __.outE('created-err'),
            __.inE('created-err').count().is(gt(1))).
              values('name')

43 Order Step

當遍歷流的對象需要排序時,可以利用order()步驟(map)。

gremlin> g.V().values('name') //不指定排序
==>marko
==>vadas
==>lop
==>josh
==>ripple
==>peter
gremlin> g.V().values('name').order() //默認升序
==>josh
==>lop
==>marko
==>peter
==>ripple
==>vadas
gremlin> g.V().values('name').order().by(decr) //聲明為降序
==>vadas
==>ripple
==>peter
==>marko
==>lop
==>josh
gremlin> g.V().values('name').order().by(shuffle) //亂序
==>ripple
==>marko
==>peter
==>vadas
==>lop
==>josh
gremlin> g.V().values('name').order().by(shuffle) //亂序
==>josh
==>ripple
==>vadas
==>lop
==>peter
==>marko

Note
shuffle來自靜態引入的Order.shuffle。

可在by()中指定排序的元素,如:

gremlin> g.V().order().by('name',decr).values('name')
==>vadas
==>ripple
==>peter
==>marko
==>lop
==>josh

44 PageRank Step

pageRank()步驟(map/sideEffect)使用PageRankVertexProgram計算PageRank。
如下,計算Modern圖中的各節點的PageRank值:

gremlin>  graph = TinkerFactory.createModern()
==>tinkergraph[vertices:6 edges:6]
gremlin> g = graph.traversal().withComputer()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], graphcomputer]
gremlin> g.V().pageRank().by('pageRank').valueMap('name','pageRank')
==>[name:[josh],pageRank:[0.19250000000000003]]
==>[name:[lop],pageRank:[0.4018125]]
==>[name:[vadas],pageRank:[0.19250000000000003]]
==>[name:[marko],pageRank:[0.15000000000000002]]
==>[name:[ripple],pageRank:[0.23181250000000003]]
==>[name:[peter],pageRank:[0.15000000000000002]]

Note:
pageRank()步驟是一個VertexComputing步驟,因此只能用於支持GraphComputer(OLAP)的圖形。

45 Path Step

path()步驟用來(map)檢查遍歷器的歷史路徑。
如發現

gremlin> g.V().out().out().values('name')
==>ripple
==>lop
gremlin> g.V().out().out().values('name').path()
==>[v[1],v[4],v[5],ripple]
==>[v[1],v[4],v[3],lop]

如果路徑中需要邊緣,那么請確保明確地遍歷這些邊。

gremlin> g.V().outE().inV().outE().inV().path()
==>[v[1],e[8][1-knows->4],v[4],e[10][4-created->5],v[5]]
==>[v[1],e[8][1-knows->4],v[4],e[11][4-created->3],v[3]]

Note
注意out()outV()區別。g.V().out()直接指向“箭頭指向的節點”,而outV()則是“發出箭頭的節點”。如:

gremlin> g.V(1).outE().outV().values('name')
==>marko
==>marko
==>marko
gremlin> g.V(1).out().out().values('name')
==>lop
==>ripple

//以下語法效果是相等的
gremlin> g.V(1).out('knows').values('name')
==>vadas
==>josh
gremlin> g.V(1).outE('knows').inV().values('name')
==>josh
==>vadas

46 PeerPressure Step

peerPressure()步驟(map/sideEffect)使用PeerPressureVertexProgram對頂點進行聚類。

gremlin> g.V().peerPressure().by('cluster').group().by('cluster').by('name')
==>[1:[marko,vadas,lop,josh,ripple],6:[peter]]

Note
peerPressure()步驟是一個VertexComputing步驟,因此只能用於支持GraphComputer(OLAP)的圖。

47 Profile Step

profile()步驟(sideEffect)允許開發人員對其遍歷進行剖析,以確定統計信息,如步驟運行時間,計數等。

gremlin> g.V().out().out().has('name','lop').values('name').profile()
==>Traversal Metrics
Step                                                               Count  Traversers       Time (ms)    % Dur
=============================================================================================================
GraphStep(vertex,[])                                                   6           6           0.057    59.90
VertexStep(OUT,vertex)                                                 6           4           0.019    20.88
VertexStep(OUT,vertex)                                                 2           2           0.009     9.48
HasStep([name.eq(lop)])                                                1           1           0.006     6.75
PropertiesStep([name],value)                                           1           1           0.002     2.99
                                            >TOTAL                     -           -           0.095        -

該步驟生成包含以下信息的TraversalMetrics sideEffect對象:

  • 步驟(Step):遍歷內的一個步驟。
  • 計數(Count):通過步驟的表示的遍歷器的數量。
  • 遍歷(Traversers):遍歷步驟的遍歷數。
  • 時間(Time/ms):步驟主動執行其行為的總時間。
  • %Dur:在步驟中花費的總時間的百分比。

當第一次遍歷加入條件‘knows’,情況就不相同,注意Count與Traversers的值:

gremlin> g.V().out('knows').out().has('name','lop').values('name').profile()
==>Traversal Metrics
Step                                                               Count  Traversers       Time (ms)    % Dur
=============================================================================================================
GraphStep(vertex,[])                                                   6           6           0.024    42.90
VertexStep(OUT,[knows],vertex)                                         2           2           0.015    27.27
VertexStep(OUT,vertex)                                                 2           2           0.013    24.46
HasStep([name.eq(lop)])                                                1           1           0.001     2.95
PropertiesStep([name],value)                                           1           1           0.001     2.42
                                            >TOTAL                     -           -           0.056        -

注意Count與Traversers的區別:

  • 遍歷器可以合並,因此當兩個遍歷器“相同”時,它們可以聚合成單個遍歷器。
  • 新的遍歷器具有Traverser.bulk(),它是兩個遍歷器的總和。
  • Count表示所有Traverser.bulk()結果的總和,因此展現的是“呈現(represented)”(非枚舉(not enumerated))遍歷器的數量。
  • Traversers總是小於Count。

Note
Count與Traversers的區別需要更多的了解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM