TinkerPop3 Gremlin 學(xué)習(xí)筆記

原文作者: 逍遙絕情
原文地址:原文鏈接
摘抄申明:我們不占有不侵權(quán)羊壹,我們只是好文的搬運(yùn)工!轉(zhuǎn)發(fā)請(qǐng)帶上原文申明叁执。

TinkerPop Gremlin基礎(chǔ)概念

  • 圖計(jì)算在結(jié)構(gòu)(圖)和過(guò)程(遍歷)之間進(jìn)行區(qū)分茄厘。

    • 圖的結(jié)構(gòu)是由頂點(diǎn)/邊/屬性拓?fù)涠x的數(shù)據(jù)模型。
    • 圖的過(guò)程是分析結(jié)構(gòu)的手段谈宛。圖形處理的典型形式稱為 遍歷次哈。
  • TinkerPop3 結(jié)構(gòu) API的主要組件:

    • Graph:維護(hù)一組頂點(diǎn)和邊,并訪問(wèn)數(shù)據(jù)庫(kù)函數(shù)(如事務(wù))吆录。

    • Element:維護(hù)一組屬性和一個(gè)表示元素類型的字符串標(biāo)簽窑滞。

    • Vertex:擴(kuò)展Element并維護(hù)一組傳入和傳出頂點(diǎn)

    • Edge:擴(kuò)展Element并維護(hù)傳入和傳出邊緣恢筝。

    • Property<V>:與V值關(guān)聯(lián)的字符串鍵哀卫。

    • VertexProperty<V>:與V值關(guān)聯(lián)的字符串鍵以及Property<U>屬性集合(僅限頂點(diǎn))

  • TinkerPop3 過(guò)程 API的主要組件

    • TraversalSource:針對(duì)特定圖形,域特定語(yǔ)言(DSL)和執(zhí)行引擎的遍歷生成器撬槽。

    • Traversal<S,E>:將類型的S對(duì)象轉(zhuǎn)換為類型對(duì)象的功能數(shù)據(jù)流程E此改。

    • GraphTraversal:面向原始圖的語(yǔ)義(即頂點(diǎn),邊等)的遍歷DSL侄柔。

    • GraphComputer:一個(gè)并行處理圖形并且可能分布在多機(jī)群集上的系統(tǒng)共啃。

    • VertexProgram:在所有頂點(diǎn)以邏輯并行方式執(zhí)行的代碼占调,通過(guò)消息傳遞進(jìn)行相互通信。

    • MapReduce:并行分析圖中所有頂點(diǎn)并產(chǎn)生單個(gè)減少結(jié)果的計(jì)算移剪。

圖形結(jié)構(gòu)

  • 結(jié)構(gòu):

    • 圖的結(jié)構(gòu)是由其頂點(diǎn)究珊,邊和屬性之間的顯式引用形成的拓?fù)洹?/li>
    • 頂點(diǎn)具有入射邊。如果一個(gè)頂點(diǎn)共享一個(gè)入射邊挂滓,則該頂點(diǎn)與另一個(gè)頂點(diǎn)相鄰苦银。
    • 一個(gè)屬性附加到一個(gè)元素上,一個(gè)元素具有一組屬性赶站。屬性是一個(gè)鍵/值對(duì)吸祟,其中鍵總是一個(gè)字符String焰枢。
Graph graph = TinkerGraph.open(); //1.創(chuàng)建一個(gè)新的內(nèi)存TinkerGraph并將其分配給該變量graph。
Vertex marko = graph.addVertex(T.label, "person", T.id, 1, "name", "marko", "age", 29); //2.創(chuàng)建一個(gè)頂點(diǎn)以及一組鍵/值對(duì)T.label作為頂點(diǎn)標(biāo)簽并且T.id是頂點(diǎn)ID。
Vertex vadas = graph.addVertex(T.label, "person", T.id, 2, "name", "vadas", "age", 27);
Vertex lop = graph.addVertex(T.label, "software", T.id, 3, "name", "lop", "lang", "java");
Vertex josh = graph.addVertex(T.label, "person", T.id, 4, "name", "josh", "age", 32);
Vertex ripple = graph.addVertex(T.label, "software", T.id, 5, "name", "ripple", "lang", "java");
Vertex peter = graph.addVertex(T.label, "person", T.id, 6, "name", "peter", "age", 35);
marko.addEdge("knows", vadas, T.id, 7, "weight", 0.5f); //3.邊緣標(biāo)簽被指定為第一個(gè)參數(shù)的同時(shí)創(chuàng)建邊緣以及一組鍵/值對(duì)碰镜。
marko.addEdge("knows", josh, T.id, 8, "weight", 1.0f);
marko.addEdge("created", lop, T.id, 9, "weight", 0.4f);
josh.addEdge("created", ripple, T.id, 10, "weight", 1.0f);
josh.addEdge("created", lop, T.id, 11, "weight", 0.4f);
peter.addEdge("created", lop, T.id, 12, "weight", 0.2f);
  • 實(shí)例分析:

    • 首先創(chuàng)建所有頂點(diǎn)Graph.addVertex(Object…?),然后創(chuàng)建它們各自的邊Vertex.addEdge(String,Vertex,Object…?)百揭。有兩個(gè)“訪問(wèn)者令牌”: T.id和T.label塞俱。
    • 相應(yīng)的元素連同提供的鍵/值對(duì)屬性一起被創(chuàng)建"name", "josh", "age", 32

遍歷過(guò)程

  • 圖表過(guò)程

    • GraphTraversalSource提供了兩種遍歷方法:

      • GraphTraversalSource.V(Object…? ids):生成從圖中頂點(diǎn)開(kāi)始的遍歷(如果沒(méi)有提供id渣窜,則為所有頂點(diǎn))铺根。

      • GraphTraversalSource.E(Object…? ids):生成從圖中邊緣開(kāi)始的遍歷(如果沒(méi)有提供id,則為所有邊)乔宿。

      • 返回類型V()和E()是GraphTraversal位迂。

      • 每種方法GraphTraversal稱為一個(gè)步驟,每個(gè)步驟以五種常規(guī)方式之一調(diào)整前一步驟的結(jié)果详瑞。

        • map:將傳入的遍歷器的對(duì)象轉(zhuǎn)換為另一個(gè)對(duì)象(S→E)掂林。

        • flatMap:將傳入的遍歷器的對(duì)象轉(zhuǎn)換為其他對(duì)象的迭代器(S→E *)。

        • filter:允許或禁止移動(dòng)機(jī)進(jìn)行下一步(S→E→S)坝橡。

        • sideEffect:允許移動(dòng)者不改變泻帮,但在過(guò)程中產(chǎn)生一些計(jì)算副作用(S?S)。

      • branch:分割移動(dòng)器并將每個(gè)發(fā)送到遍歷中的任意位置(S→{S 1 →E *计寇,…锣杂,S n →E *}→E *)。

    • Nearly every step in GraphTraversal either extends MapStep, FlatMapStep, FilterStep, SideEffectStep, or BranchStep.

$ bin/gremlin.sh

         \,,,/
         (o o)
-----oOOo-(3)-oOOo-----
gremlin> graph = TinkerFactory.createModern() //1.打開(kāi)玩具圖并通過(guò)變量引用它graph番宁。
==>tinkergraph[vertices:6 edges:6]
gremlin> g = graph.traversal()        //2.使用標(biāo)準(zhǔn)的OLTP遍歷引擎從圖中創(chuàng)建一個(gè)圖遍歷源蹲堂。
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().has('name','marko').out('knows').values('name') //3.從遍歷源中產(chǎn)生一個(gè)遍歷,以確定標(biāo)記頂點(diǎn)知道的人的名字贝淤。
==>vadas
==>josh
gremlin> marko = g.V().has('name','marko').next() //1.將變量設(shè)置為名為“marko” marko的圖形中的頂點(diǎn)g柒竞。
==>v[1]
gremlin> g.V(marko).out('knows') //2.通過(guò)知識(shí)邊獲取與標(biāo)記頂點(diǎn)相鄰的傳出頂點(diǎn)。
==>v[2]
==>v[4]
gremlin> g.V(marko).out('knows').values('name') //3.獲取marko-vertex的朋友的名字播聪。
==>vadas
==>josh
  • 遍歷器的路徑歷史記錄
gremlin> g.V(marko).out('knows').values('name').path()
==>[v[1],v[2],vadas]
==>[v[1],v[4],josh]
  • 遍歷器遍歷遍歷表達(dá)式的特定部分(即循環(huán))的次數(shù)
gremlin> g.V(marko).repeat(out()).times(2).values('name')
==>ripple
==>lop

頂點(diǎn)屬性

  • a的所有屬性Vertex都是a VertexProperty朽基。A VertexProperty實(shí)現(xiàn)Property布隔,因此它有一個(gè)鍵/值對(duì)。

  • 但是稼虎,VertexProperty也可以實(shí)現(xiàn)Element并因此可以具有鍵/值對(duì)的集合

  • 雖然Edge只能有一個(gè)“name”鍵的屬性衅檀,但是Vertex可以有多個(gè)“name”屬性。通過(guò)包含頂點(diǎn)屬性霎俩,引入了兩個(gè)功能哀军,最終推進(jìn)了圖形建模工具包:

    • 多個(gè)屬性(多屬性):頂點(diǎn)屬性鍵可以有多個(gè)值。例如打却,一個(gè)頂點(diǎn)可以有多個(gè)“name”屬性杉适。
    • Properties on properties(元屬性):頂點(diǎn)屬性可以具有屬性(即,頂點(diǎn)屬性可以具有與其關(guān)聯(lián)的鍵/值數(shù)據(jù))

圖事務(wù)

  • 一個(gè)數(shù)據(jù)庫(kù)事務(wù) 代表的工作單位來(lái)對(duì)數(shù)據(jù)庫(kù)執(zhí)行柳击。
  • 事務(wù)由Transaction接口的實(shí)現(xiàn)控制猿推, 并且該對(duì)象可以Graph使用該tx()方法從接口獲取。
  • 請(qǐng)注意捌肴,該Transaction對(duì)象本身并不代表“事務(wù)”蹬叭。它只是公開(kāi)了處理事務(wù)的方法(例如提交,回滾等)状知。
  • 大部分Graph是實(shí)現(xiàn)supportsTransactions將實(shí)現(xiàn)“自動(dòng)” ThreadLocal交易秽五,這意味著當(dāng)后一個(gè)讀或?qū)懖僮鲿r(shí)Graph被實(shí)例化,事務(wù)就會(huì)自動(dòng)線程內(nèi)開(kāi)始饥悴。
  • 沒(méi)有必要手動(dòng)調(diào)用一個(gè)方法來(lái)“創(chuàng)建”或“啟動(dòng)”一個(gè)事務(wù)坦喘。只需根據(jù)需要修改圖形,然后致電graph.tx().commit()以應(yīng)用更改或graph.tx().rollback()撤消它們铺坞。當(dāng)下一個(gè)讀取或?qū)懭氩僮靼l(fā)生在圖上時(shí)起宽,將在當(dāng)前執(zhí)行線程中啟動(dòng)一個(gè)新的事務(wù)洲胖。

遍歷

  • 遍歷由四個(gè)主要組成部分組成:

    • Step<S,E>:應(yīng)用于S產(chǎn)出的單個(gè)函數(shù)E济榨。步驟在遍歷內(nèi)鏈接。

    • TraversalStrategy:攔截器方法來(lái)改變遍歷的執(zhí)行(例如查詢重寫)绿映。

    • TraversalSideEffects:可用于存儲(chǔ)有關(guān)遍歷的全局信息的鍵/值對(duì)擒滑。

    • Traverser<T>:通過(guò)Traversal當(dāng)前表示類型的對(duì)象傳播的對(duì)象T。

  • 圖形遍歷的經(jīng)典概念GraphTraversal<S,E>由此擴(kuò)展而來(lái)Traversal<S,E>叉弦。 GraphTraversal根據(jù)頂點(diǎn)丐一,邊緣等提供對(duì)圖數(shù)據(jù)的解釋,并因此提供圖遍歷DSL淹冰。

    這里寫圖片描述

  • 該Traverser<S>對(duì)象可以訪問(wèn):

    • 當(dāng)前遍歷的S對(duì)象 -? Traverser.get()库车。

    • 遍歷器遍歷的當(dāng)前路徑 -? Traverser.path()。

    • 獲取特定路徑歷史對(duì)象的助手速記 -? Traverser.path(String) == Traverser.path().get(String)樱拴。

    • 遍歷器通過(guò)當(dāng)前循環(huán)的次數(shù) -? Traverser.loops()柠衍。

    • 這個(gè)遍歷器表示的對(duì)象的數(shù)量 -? Traverser.bulk()洋满。

    • 與此遍歷器相關(guān)的本地?cái)?shù)據(jù)結(jié)構(gòu) -? Traverser.sack()。

    • 與遍歷相關(guān)的副作用 -? Traverser.sideEffects()珍坊。

gremlin> g.V(1).out().values('name') //1.從頂點(diǎn)1到相鄰頂點(diǎn)的名稱值的傳出遍歷牺勾。
==>lop
==>vadas
==>josh
gremlin> g.V(1).out().map {it.get().value('name')} //2.相同的操作,但使用lambda來(lái)訪問(wèn)名稱屬性值阵漏。
==>lop
==>vadas
==>josh
gremlin> g.V(1).out().map(values('name')) //3.同樣的操作驻民,但使用遍歷表示map()。
==>lop
==>vadas
==>josh
gremlin> g.V().filter {it.get().label() == 'person'} //1.如果過(guò)濾器具有“人物”標(biāo)簽履怯,則只允許頂點(diǎn)通過(guò)
==>v[1]
==>v[2]
==>v[4]
==>v[6]
gremlin> g.V().filter(label().is('person')) //2.如果過(guò)濾器具有“人物”標(biāo)簽回还,則只允許頂點(diǎn)通過(guò)
==>v[1]
==>v[2]
==>v[4]
==>v[6]
gremlin> g.V().hasLabel('person') //3.更具體的步驟has()是filter()用各自的謂詞來(lái)實(shí)現(xiàn)的。
==>v[1]
==>v[2]
==>v[4]
==>v[6]
gremlin> g.V().branch {it.get().value('name')}.
               option('marko', values('age')).
               option(none, values('name')) //1.如果頂點(diǎn)是“marko”虑乖,則獲取他的年齡懦趋,否則獲取頂點(diǎn)的名稱。
==>29
==>vadas
==>lop
==>josh
==>ripple
==>peter
gremlin> g.V().branch(values('name')).
               option('marko', values('age')).
               option(none, values('name')) //2.相同的操作疹味,但使用遍歷表示branch()仅叫。
==>29
==>vadas
==>lop
==>josh
==>ripple
==>peter
gremlin> g.V().choose(has('name','marko'),
                      values('age'),
                      values('name')) //3.更具體的基于布爾的步驟choose()被實(shí)現(xiàn)為a branch()。
==>29
==>vadas
==>lop
==>josh
==>ripple
==>peter

Terminal

  • 通常糙捺,當(dāng)一個(gè)步驟連接到一個(gè)遍歷時(shí)诫咱,返回一個(gè)遍歷。通過(guò)這種方式洪灯,流暢的坎缭,單點(diǎn)式的遍歷就可以建立起來(lái)。
  • 但是签钩,某些步驟不會(huì)返回遍歷掏呼,而是執(zhí)行遍歷并返回結(jié)果。這些步驟被稱為終端步驟(終端)
gremlin> g.V().out('created').hasNext() //1.hasNext() 確定是否有可用的結(jié)果铅檩。
==>true
gremlin> g.V().out('created').next() //2.next() 將返回下一個(gè)結(jié)果憎夷。
==>v[3]
gremlin> g.V().out('created').next(2) //3.next(n)將返回n列表中的下一個(gè)結(jié)果。
==>v[3]
==>v[5]
gremlin> g.V().out('nothing').tryNext() //4.tryNext()將返回一個(gè)Optional昧旨,因此拾给,是hasNext()/ 的組合next()。
==>Optional.empty
gremlin> g.V().out('created').toList() //5.tryNext()將返回一個(gè)Optional兔沃,因此蒋得,是hasNext()/ 的組合next()。
==>v[3]
==>v[5]
==>v[3]
==>v[3]
gremlin> g.V().out('created').toSet() //6.toSet() 將返回一個(gè)集合中的所有結(jié)果(因此乒疏,重復(fù)刪除)额衙。
==>v[3]
==>v[5]
gremlin> g.V().out('created').toBulkSet() //7.toBulkSet() 將返回加權(quán)集合中的所有結(jié)果(因此,通過(guò)加權(quán)保留重復(fù))。
==>v[3]
==>v[3]
==>v[3]
==>v[5]
gremlin> results = ['blah',3]
==>blah
==>3
gremlin> g.V().out('created').fill(results) //8.fill(collection) 會(huì)將所有結(jié)果放入提供的集合中窍侧,并在完成時(shí)返回集合追驴。
==>blah
==>3
==>v[3]
==>v[5]
==>v[3]
==>v[3]
gremlin> g.addV('person').iterate() // 9.iterate() 并不完全符合終端步驟的定義,因?yàn)樗环祷亟Y(jié)果疏之,但仍然返回一個(gè)遍歷 - 但它確實(shí)表現(xiàn)為終端步驟殿雪,它重復(fù)遍歷并生成副作用而不返回實(shí)際結(jié)果。

AddEdge

  • 推理是明確數(shù)據(jù)中隱含的內(nèi)容的過(guò)程.

  • 圖中顯式的是圖的對(duì)象 - 即頂點(diǎn)锋爪。

  • 圖中隱含的是遍歷丙曙。

    • 換句話說(shuō),遍歷揭示了意義由遍歷定義確定的位置其骄。
gremlin> g.V(1).as('a').out('created').in('created').where(neq('a')).
           addE('co-developer').from('a').property('year',2009) //1.在marko和他的合作者之間添加一個(gè)年度財(cái)產(chǎn)的合作開(kāi)發(fā)者邊緣亏镰。
==>e[13][1-co-developer->4]
==>e[14][1-co-developer->6]
gremlin> g.V(3,4,5).aggregate('x').has('name','josh').as('a').
           select('x').unfold().hasLabel('software').addE('createdBy').to('a') //2.將來(lái)自josh頂點(diǎn)的傳入createdBy邊添加到lop和波紋頂點(diǎn)。
==>e[15][3-createdBy->4]
==>e[16][5-createdBy->4]
gremlin> g.V().as('a').out('created').addE('createdBy').to('a').property('acl','public') //3.為所有創(chuàng)建的邊添加一個(gè)反向創(chuàng)建的邊拯爽。
==>e[17][3-createdBy->1]
==>e[18][5-createdBy->4]
==>e[19][3-createdBy->4]
==>e[20][3-createdBy->6]
gremlin> g.V(1).as('a').out('knows').
           addE('livesNear').from('a').property('year',2009).
           inV().inE('livesNear').values('year') //4.新創(chuàng)建的邊是一個(gè)可遍歷的對(duì)象索抓。
==>2009
==>2009
gremlin> g.V().match(
                 __.as('a').out('knows').as('b'),
                 __.as('a').out('created').as('c'),
                 __.as('b').out('created').as('c')).
               addE('friendlyCollaborator').from('a').to('b').
                 property(id,23).property('project',select('c').values('name')) //5.可以加入遍歷中的任意兩個(gè)綁定from()→ , where `id可以為支持用戶提供的id的圖提供`to()。
==>e[23][1-friendlyCollaborator->4]
gremlin> g.E(23).valueMap()
==>[project:lop]
gremlin> marko = g.V().has('name','marko').next()
==>v[1]
gremlin> peter = g.V().has('name','peter').next()
==>v[6]
gremlin> g.V(marko).addE('knows').to(peter) //6.給定定向(分離)的頂點(diǎn)參考毯炮,在marko和peter之間添加一條邊逼肯。
==>e[24][1-knows->6]
gremlin> g.addE('knows').from(marko).to(peter) //7.給定定向(分離)的頂點(diǎn)參考,在marko和peter之間添加一條邊桃煎。
==>e[25][1-knows->6]

AddVertex

  • 所述addV()-step用于頂點(diǎn)添加到圖表(map/ sideEffect)篮幢。
  • 對(duì)于每個(gè)傳入的對(duì)象,都會(huì)創(chuàng)建一個(gè)頂點(diǎn)为迈。此外三椿,GraphTraversalSource維護(hù)一個(gè)addV()方法。
gremlin> g.addV('person').property('name','stephen')
==>v[13]
gremlin> g.V().values('name')
==>marko
==>vadas
==>lop
==>josh
==>ripple
==>peter
==>stephen
gremlin> g.V().outE('knows').addV().property('name','nothing')
==>v[15]
==>v[17]
gremlin> g.V().has('name','nothing')
==>v[17]
==>v[15]
gremlin> g.V().has('name','nothing').bothE()

AddProperty

  • The property():步驟用于將屬性添加到的曲線圖的元素sideEffect葫辐。
  • 不像addV()和 addE()搜锰,property()是一個(gè)完整的sideEffect一步,因?yàn)樗粫?huì)返回它創(chuàng)造的財(cái)產(chǎn)耿战,而是涌入它的元素蛋叼。
gremlin> g.V(1).property('country','usa')
==>v[1]
gremlin> g.V(1).property('city','santa fe').property('state','new mexico').valueMap()
==>[country:[usa],city:[santa fe],name:[marko],state:[new mexico],age:[29]]
gremlin> g.V(1).property(list,'age',35) //1.對(duì)于頂點(diǎn),可以為頂點(diǎn)屬性提供基數(shù)昆箕。
==>v[1]
gremlin> g.V(1).valueMap()
==>[country:[usa],city:[santa fe],name:[marko],state:[new mexico],age:[29,35]]
gremlin> g.V(1).property('friendWeight',outE('knows').values('weight').sum(),'acl','private') //2.可以通過(guò)遍歷來(lái)選擇屬性值(以及鍵)鸦列。
==>v[1]
gremlin> g.V(1).properties('friendWeight').valueMap() //3.對(duì)于頂點(diǎn)租冠,property()-step可以添加元屬性鹏倘。
==>[acl:private]

Aggregate

  • aggregate()工序(sideEffect)用于在特定點(diǎn)遍歷成聚集的所有對(duì)象 Collection。
  • The step uses eager evaluation in that no objects continue on until all previous objects have been fully aggregated (as opposed to store() which lazily fills a collection). The eager evaluation nature is crucial in situations where everything at a particular point is required for future computation. An example is provided below.
gremlin> g.V(1).out('created') //1顽爹。marko創(chuàng)建了什么纤泵?
==>v[3]
gremlin> g.V(1).out('created').aggregate('x') //2。匯總他所有的創(chuàng)作。
==>v[3]
gremlin> g.V(1).out('created').aggregate('x').in('created') //3捏题。誰(shuí)是marko的合作者玻褪?
==>v[1]
==>v[4]
==>v[6]
gremlin> g.V(1).out('created').aggregate('x').in('created').out('created') //4。marko的合作者創(chuàng)造了什么公荧?
==>v[3]
==>v[5]
==>v[3]
==>v[3]
gremlin> g.V(1).out('created').aggregate('x').in('created').out('created').
                where(without('x')).values('name') //5带射。Marko的合作者創(chuàng)建了什么,他沒(méi)有創(chuàng)建循狰?
==>ripple

And

  • The and():確保所有提供遍歷得到的結(jié)果(濾波)
gremlin> g.V().and(
            outE('knows'),
            values('age').is(lt(30))).
              values('name')
==>marko
  • 一個(gè)中間符號(hào)可以被使用窟社。盡管用中綴符號(hào)表示,但只有兩次遍歷可以在一起绪钥。
gremlin> g.V().where(outE('created').and().outE('knows')).values('name')
==>marko

As

  • The as():不是一個(gè)真正的步驟灿里,而是一個(gè)類似于by()和的“步調(diào)制器” option()。
  • 用as()程腹,有可能提供一個(gè)標(biāo)簽到可稍后通過(guò)步驟和數(shù)據(jù)結(jié)構(gòu)匣吊,使這些標(biāo)記的使用被訪問(wèn)的步驟-例如select(),match()和路徑寸潦。
gremlin> g.V().as('a').out('created').as('b').select('a','b') //1.從路徑中選擇標(biāo)記為“a”和“b”的對(duì)象色鸳。
==>[a:v[1],b:v[3]]
==>[a:v[4],b:v[5]]
==>[a:v[4],b:v[3]]
==>[a:v[6],b:v[3]]
gremlin> g.V().as('a').out('created').as('b').select('a','b').by('name') //2.從路徑中選擇標(biāo)記為“a”和“b”的對(duì)象,并為每個(gè)對(duì)象設(shè)置其名稱值见转。
==>[a:marko,b:lop]
==>[a:josh,b:ripple]
==>[a:josh,b:lop]
==>[a:peter,b:lop]
  • 一個(gè)步驟可以有任何數(shù)量的標(biāo)簽與之相關(guān)聯(lián)缕碎。這對(duì)于在未來(lái)的步驟中多次引用同一步驟很有用。
gremlin> g.V().hasLabel('software').as('a','b','c').
            select('a','b','c').
              by('name').
              by('lang').
              by(__.in('created').values('name').fold())
==>[a:lop,b:java,c:[marko,josh,peter]]
==>[a:ripple,b:java,c:[josh]]

Barrier

  • The barrier():(屏障)變?yōu)閼卸璞闅v流水線成批量同步管道池户。

  • 此步驟很有用:

    • 當(dāng)所有的事情都需要被執(zhí)行之后才能進(jìn)入barrier()(即排序)之后的步驟咏雌。
    • 當(dāng)“stalling”遍歷可能導(dǎo)致遍歷中的“bulking optimization”,這種遍歷反復(fù)觸及許多相同的元素(即優(yōu)化)校焦。
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]
  • “bulking optimization”背后的理論很簡(jiǎn)單赊抖。
  • 如果在頂點(diǎn)1處有一百萬(wàn)個(gè)遍歷器,則不需要計(jì)算一百萬(wàn)個(gè)both()計(jì)算寨典。相反氛雪,將這100萬(wàn)遍歷作為一個(gè)Traverser.bulk()等于一百萬(wàn)的遍歷器來(lái)表示,并執(zhí)行both()一次耸成。
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.io(graphml()).readGraph('data/grateful-dead.xml')
gremlin> g = graph.traversal().withoutStrategies(LazyBarrierStrategy) //1.明確地刪除LazyBarrierStrategy這會(huì)產(chǎn)生一個(gè)膨脹優(yōu)化报亩。
==>graphtraversalsource[tinkergraph[vertices:808 edges:8049], standard]
gremlin> clockWithResult(1){g.V().both().both().both().count().next()} //2.處理每個(gè)移動(dòng)程序的非擴(kuò)充遍歷。
==>10555.215011999999
==>126653966
gremlin> clockWithResult(1){g.V().repeat(both()).times(3).count().next()} //3.每個(gè)進(jìn)入者repeat()都有其遞歸權(quán)重井氢。
==>32.586223
==>126653966
gremlin> clockWithResult(1){g.V().both().barrier().both().barrier().both().barrier().count().next()} //4.沒(méi)有處理隱式遍歷的遍歷遍歷弦追。
==>24.458371
==>126653966
  • 如果barrier()提供了一個(gè)整數(shù)參數(shù),那么在將n聚合遍歷器排空到下一步之前花竞,屏障將只保留唯一遍歷器的數(shù)量劲件。
  • LazyBarrierStrategy插入 - barrier()在適當(dāng)?shù)牡胤竭M(jìn)行遍歷,以獲得“膨脹優(yōu)化”。
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.io(graphml()).readGraph('data/grateful-dead.xml')
gremlin> g = graph.traversal() //1.LazyBarrierStrategy 是一種默認(rèn)策略零远,因此不需要明確激活苗分。
==>graphtraversalsource[tinkergraph[vertices:808 edges:8049], standard]
gremlin> clockWithResult(1){g.V().both().both().both().count().next()}
==>15.593098999999999
==>126653966
gremlin> g.V().both().both().both().count().iterate().toString() //2.與LazyBarrierStrategy激活,barrier()步驟被自動(dòng)插入在適當(dāng)情況下牵辣。
==>[TinkerGraphStep(vertex,[]), VertexStep(BOTH,vertex), NoOpBarrierStep(2500), VertexStep(BOTH,vertex), NoOpBarrierStep(2500), VertexStep(BOTH,edge), CountGlobalStep, NoneStep]

By

  • The by():一步不是一個(gè)實(shí)際的步驟摔癣,而是一個(gè)類似于as()和 的“階躍調(diào)節(jié)器” 。
  • 如果一個(gè)步驟能夠接受遍歷纬向,函數(shù)供填,比較等,那么by()就是它們被添加的方式罢猪。一般模式是step().by()…?by()近她。有些步驟只能接受一個(gè),by() 而其他步驟可以采取任意數(shù)量膳帕。
gremlin> g.V().group().by(outE().count()) //1.by(outE().count())將按元素的邊數(shù)(遍歷)對(duì)元素進(jìn)行分組粘捎。
==>[1:[v[2],v[5],v[6]],3:[v[1],v[3],v[4]]]
gremlin> g.V().group().by(bothE().count()).by('name') //2.by('name')將按名稱處理分組元素(元素屬性投影)。
==>[1:[vadas,ripple,peter],3:[marko,lop,josh]]
gremlin> g.V().group().by(bothE().count()).by(count()) //3.by(count())將計(jì)算每個(gè)組中元素的數(shù)量(遍歷)危彩。
==>[1:3,3:3]
  • 以下步驟都支持by()調(diào)制:

    • dedup():對(duì)調(diào)制結(jié)果進(jìn)行by()重復(fù)數(shù)據(jù)刪除攒磨。

    • cyclicPath():如果遍歷器的路徑是循環(huán)給定by()調(diào)制,則進(jìn)行過(guò)濾汤徽。

    • simplePath():如果遍歷器的路徑在給定by()調(diào)制的情況下是簡(jiǎn)單的娩缰,則進(jìn)行過(guò)濾。

    • sample():使用由by()調(diào)制返回的值進(jìn)行采樣谒府。

    • where():確定給定測(cè)試結(jié)果的謂詞 - by()調(diào)制拼坎。

    • groupCount():計(jì)數(shù)那些組密鑰是by()調(diào)制結(jié)果的組。

    • group():根據(jù)by()-modulation 創(chuàng)建組鍵和值完疫。

    • order():通過(guò)by()調(diào)制的結(jié)果對(duì)對(duì)象進(jìn)行排序泰鸡。

    • path():獲取每個(gè)路徑元素被by()調(diào)制的遍歷器的路徑。

    • project():by()從當(dāng)前對(duì)象中投影給定各種調(diào)制結(jié)果的地圖壳鹤。

    • select():選擇路徑元素并通過(guò)by()調(diào)制進(jìn)行轉(zhuǎn)換盛龄。

    • tree():獲取對(duì)象已被by()調(diào)制的遍歷器對(duì)象樹(shù)。

    • aggregate():將所有對(duì)象聚合到一個(gè)集合中芳誓,但只存儲(chǔ)它們的by()-modulated值余舶。

    • store():將所有對(duì)象存儲(chǔ)到一個(gè)集合中,但只存儲(chǔ)它們的by()-modulated值锹淌。

Cap

  • The cap(): 迭代遍歷到本身并發(fā)射通過(guò)所提供的密鑰所引用的sideEffect匿值。如果提供了多個(gè)鍵,則會(huì)Map
gremlin> g.V().groupCount('a').by(label).cap('a') //1.按標(biāo)簽對(duì)頂點(diǎn)進(jìn)行分組和計(jì)數(shù)葛圃。發(fā)出標(biāo)記為'a'的副作用千扔,這是按標(biāo)簽計(jì)算的組數(shù)。
==>[software:2,person:4]
gremlin> g.V().groupCount('a').by(label).groupCount('b').by(outE().count()).cap('a','b') //2.與語(yǔ)句1相同库正,但也會(huì)發(fā)出標(biāo)記為'b'的副作用曲楚,該副作用按照出邊的數(shù)量對(duì)頂點(diǎn)進(jìn)行分組。
==>[a:[software:2,person:4],b:[0:3,1:1,2:1,3:1]]

Choose

  • The choose():(分支)的路線橫移到一個(gè)特定的遍歷分支選項(xiàng)褥符。
  • 有了choose()它龙誊,就可以實(shí)現(xiàn)if / then / else-semantics以及更復(fù)雜的選擇。
gremlin> g.V().hasLabel('person').
               choose(values('age').is(lte(30)),
                 __.in(),
                 __.out()).values('name') //1.如果遍歷產(chǎn)生一個(gè)元素喷楣,那么do in趟大,else do out(即基于true / false的選項(xiàng)選擇)。
==>marko
==>ripple
==>lop
==>lop
gremlin> g.V().hasLabel('person').
               choose(values('age')).
                 option(27, __.in()).
                 option(32, __.out()).values('name') //2.使用遍歷的結(jié)果作為遍歷選項(xiàng)的映射關(guān)鍵(即基于值的選項(xiàng)選擇)铣焊。
==>marko
==>ripple
==>lop
  • 請(qǐng)注意逊朽,choose()可以有任意數(shù)量的選項(xiàng),而且可以采用匿名遍歷作為其選擇功能曲伊。
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() 可以利用Pick.none選項(xiàng)匹配叽讳。對(duì)于與指定選項(xiàng)不匹配的任何內(nèi)容,將采用none-option坟募。
gremlin> g.V().hasLabel('person').
               choose(values('name')).
                 option('marko', values('age')).
                 option(none, values('name'))
==>29
==>vadas
==>josh
==>peter

Coalesce 合并

  • This coalesce(): 評(píng)估岛蚤,以便所提供的遍歷,并返回該發(fā)射的至少一種元素的第一遍歷懈糯。
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

Coin

  • This coin():要隨機(jī)篩選出一個(gè)遍歷器.
  • 提供的雙重論點(diǎn)偏向于“擲硬幣”涤妒。
gremlin> g.V().coin(0.5)
==>v[1]
==>v[2]
==>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]

Constant 常量

  • This constant():要為移動(dòng)器指定常量值
  • 通常適用于像choose()-step或coalesce()-step這樣的條件步驟。
gremlin> g.V().choose(hasLabel('person'),
             values('name'),
             constant('inhuman')) //1.顯示人物的名字赚哗,但顯示其他頂點(diǎn)的“inhuman”她紫。
==>marko
==>vadas
==>inhuman
==>josh
==>inhuman
==>peter
gremlin> g.V().coalesce(
             hasLabel('person').values('name'),
             constant('inhuman')) //2.與陳述1相同(除非有沒(méi)有名字的人頂點(diǎn))。
==>marko
==>vadas
==>inhuman
==>josh
==>inhuman
==>peter

Count 計(jì)數(shù)

  • This count():對(duì)在該流表示traversers的總數(shù)(即屿储,批量計(jì)數(shù))犁苏。
gremlin> g.V().count()
==>6
gremlin> g.V().hasLabel('person').count()
==>4
gremlin> g.V().hasLabel('person').outE('created').count().path() //1.count()-step是一個(gè)減少的屏障步驟,意味著所有以前的遍歷器都被折疊成一個(gè)新的遍歷器扩所。
==>[4]
gremlin> g.V().hasLabel('person').outE('created').count().map {it.get() * 10}.path() //2.從... count()開(kāi)始的移動(dòng)器的路徑從count()围详。
==>[4,40]

CyclicPath 循環(huán)路徑

  • 每個(gè)遍歷器通過(guò)遍歷圖 - 即其路徑來(lái)維護(hù)其歷史。如果遍歷器重復(fù)它的過(guò)程很重要祖屏,那么cyclic()應(yīng)該使用-path(過(guò)濾器)
  • 該步驟至此分析遍歷器的路徑助赞,并且如果有任何重復(fù),遍歷器將在遍歷計(jì)算中被濾除袁勺。如果需要非循環(huán)行為雹食,請(qǐng)參閱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()

Dedup 刪除重復(fù)

  • This dedup():反復(fù)看到的對(duì)象將從遍歷流中移除期丰。
  • 請(qǐng)注意群叶,如果移動(dòng)器的體積大于1吃挑,則在發(fā)射之前將其設(shè)置為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() //1街立。遍歷所有created邊舶衬,但不要碰兩邊。
==>[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]]
  • 如果提供了逐步調(diào)制dedup()赎离,則在確定是否已經(jīng)看到對(duì)象之前對(duì)該對(duì)象進(jìn)行相應(yīng)處理逛犹。
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()提供了一個(gè)字符串?dāng)?shù)組,那么它將確保重復(fù)數(shù)據(jù)刪除不是針對(duì)當(dāng)前的遍歷器對(duì)象梁剔,而是針對(duì)遍歷器的路徑歷史記錄虽画。
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') //1。如果之前已經(jīng)看到電流a和b組合荣病,則過(guò)濾移動(dòng)器码撰。
==>[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]]

Drop 下降

  • This drop():用于除去從所述圖形元素和屬性(即刪除)。
  • 這是一個(gè)過(guò)濾步驟个盆,因?yàn)楸闅v不會(huì)產(chǎn)生傳出對(duì)象灸拍。
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()

Emit

  • This emit():不是實(shí)際的一步,但不是為一個(gè)步調(diào)制器repeat()(找到更多的文檔emit()存在)砾省。

Explain 解釋

  • This explain():(終端)將返回一個(gè)TraversalExplanation鸡岗。

  • 遍歷解釋詳細(xì)說(shuō)明了遍歷(之前explain())將如何在給定注冊(cè)遍歷策略的情況下編譯。

  • A TraversalExplanation具有toString()3列的表示编兄。

    • 第一列是應(yīng)用的遍歷策略轩性。
    • 第二列是遍歷策略類別:[D]生態(tài)化,[O]優(yōu)化狠鸳,[P]漫游器優(yōu)化揣苏,[F]實(shí)現(xiàn)和[V]驗(yàn)證。
    • 最后件舵,第三列是遍歷后策略應(yīng)用程序的狀態(tài)卸察。最后的遍歷是由此產(chǎn)生的執(zhí)行計(jì)劃。
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))]
RepeatUnrollStrategy         [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))]
MatchPredicateStrategy       [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))]
FilterRankingStrategy        [O]   [GraphStep(vertex,[]), HasStep([~label.eq(person)]), VertexStep(OUT,edge), IdentityStep, EdgeVertexStep(IN), RangeGlobalStep(0,6), CountGlobalStep, IsStep(gt(5))]
InlineFilterStrategy         [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))]

Fold 折疊

  • 遍歷流需要一個(gè)“屏障”來(lái)聚合所有對(duì)象并發(fā)出一個(gè)計(jì)算函數(shù)作為聚合函數(shù)
gremlin> g.V(1).out('knows').values('name')
==>vadas
==>josh
gremlin> g.V(1).out('knows').values('name').fold() //1铅祸。無(wú)參數(shù)fold()會(huì)將所有對(duì)象聚合到列表中坑质,然后發(fā)出列表。
==>[vadas,josh]
gremlin> g.V(1).out('knows').values('name').fold().next().getClass() //2临梗。無(wú)參數(shù)fold()會(huì)將所有對(duì)象聚合到列表中涡扼,然后發(fā)出列表。
==>class java.util.ArrayList
gremlin> g.V(1).out('knows').values('name').fold(0) {a,b -> a + b.length()} //3盟庞。fold() 可以提供兩個(gè)參數(shù) - 一個(gè)種子值和一個(gè)減少雙向函數(shù)(“vadas”是5個(gè)字符+“josh”吃沪,4個(gè)字符)。
==>9
gremlin> g.V().values('age').fold(0) {a,b -> a + b} //4什猖。圖中人的總年齡是多少票彪?
==>123
gremlin> g.V().values('age').fold(0, sum) //5红淡。與以前一樣,但使用內(nèi)置的雙功能降铸。
==>123
gremlin> g.V().values('age').sum() //6在旱。與以前一樣,但使用內(nèi)置的雙功能垮耳。
==>123

From

  • This from():不是一個(gè)實(shí)際的步驟颈渊,而是一個(gè)類似于as()和 的“階躍調(diào)節(jié)器” by()遂黍。
  • 如果一個(gè)步驟能夠接受遍歷或字符串终佛,那么from()它們就是添加它們的手段。一般模式是step().from()雾家。見(jiàn) - to()步铃彰。
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]

Graph

  • This graph():通常用于啟動(dòng)GraphTraversal,但也可以使用中間穿越芯咧。
remlin> g.V().has('name', within('marko', 'vadas', 'josh')).as('person').
           V().has('name', within('lop', 'ripple')).addE('uses').from('person').toString() //1牙捉。通常這個(gè)步驟V()將遍歷所有的頂點(diǎn)。但是敬飒,圖策略可以折疊HasContainer’s into a `GraphStep以允許索引查找邪铲。
==>[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() //2。圖形系統(tǒng)提供者是否支持中間遍歷V()索引查找可以通過(guò)檢查toString()迭代遍歷的輸出來(lái)輕松確定无拗。如果has條件被折疊成步驟带到,則將V()使用索引(如果存在的話)。
==>[TinkerGraphStep(vertex,[name.within([marko, vadas, josh])])@[person], TinkerGraphStep(vertex,[name.within([lop, ripple])]), AddEdgeStep({~from=[[SelectOneStep(last,person)]], label=[uses]}), NoneStep]

Group 組

  • 當(dāng)遍歷器遍歷一個(gè)由遍歷定義的圖時(shí)英染,有時(shí)需要sideEffect計(jì)算揽惹。
  • 也就是說(shuō),所采用的實(shí)際路徑或者移動(dòng)器的當(dāng)前位置不是計(jì)算的最終輸出四康,而是遍歷的一些其他表示搪搏。
  • 所述group()工序(地圖 / sideEffect)就是這樣一種sideEffect,根據(jù)對(duì)象的某些功能組織的對(duì)象闪金。然后疯溺,如果需要,該組織(列表)將減少哎垦。
gremlin> g.V().group().by(label) //1.按照它們的標(biāo)簽對(duì)頂點(diǎn)進(jìn)行分組喝检。
==>[software:[v[3],v[5]],person:[v[1],v[2],v[4],v[6]]]
gremlin> g.V().group().by(label).by('name') //2.對(duì)于組中的每個(gè)頂點(diǎn),獲取它們的名稱撼泛。
==>[software:[lop,ripple],person:[marko,vadas,josh,peter]]
gremlin> g.V().group().by(label).by(count()) //3.對(duì)于每個(gè)分組挠说,它的大小是多少?
==>[software:2,person:4]
  • 可以group()通過(guò)的兩個(gè)投影參數(shù)by()是:

    • Key-projection:組合對(duì)象的哪個(gè)特征(產(chǎn)生map鍵的函數(shù))

    • 價(jià)值投影:該組的哪些功能要存儲(chǔ)在密鑰列表中

GroupCount 分組統(tǒng)計(jì)

  • This groupCount():特定對(duì)象在遍歷的特定部分有多少次
gremlin> g.V().hasLabel('person').values('age').groupCount()
==>[32:1,35:1,27:1,29:1]
gremlin> g.V().hasLabel('person').groupCount().by('age') //1.您還可以提供預(yù)組投影愿题,其中提供的by()調(diào)制決定了將傳入對(duì)象分組的內(nèi)容。
==>[32:1,35:1,27:1,29:1]

Has 有

  • This has():根據(jù)其屬性過(guò)濾頂點(diǎn)曹货,邊和頂點(diǎn)屬性亮垫。有很多變化,has()包括:

    • has(key,value):如果元素沒(méi)有提供的鍵/值屬性雁仲,則移除該移動(dòng)器。

    • has(label, key, value):如果元素沒(méi)有指定的標(biāo)簽并提供鍵/值屬性琐脏,則移除該移動(dòng)器攒砖。

    • has(key,predicate):如果元素沒(méi)有滿足雙謂詞的鍵值,則移除該移動(dòng)器日裙。有關(guān)謂詞的更多信息吹艇,請(qǐng)閱讀關(guān)于謂詞的注釋。

    • hasLabel(labels…?):如果元素沒(méi)有任何標(biāo)簽昂拂,則移除移動(dòng)器受神。

    • hasId(ids…?):如果元素沒(méi)有任何id,則移除移動(dòng)器格侯。

    • hasKey(keys…?):如果屬性沒(méi)有提供所有提供的鍵鼻听,則移除移動(dòng)器。

    • hasValue(values…?):如果移動(dòng)器的屬性沒(méi)有提供所有提供的值联四,則移除移動(dòng)器撑碴。

    • has(key):如果移動(dòng)元素的元素沒(méi)有鍵值,則移除移動(dòng)元素朝墩。

    • hasNot(key):如果元素的值為該鍵醉拓,則移除該移動(dòng)器。

    • has(key, traversal):如果移動(dòng)器的對(duì)象沒(méi)有通過(guò)遍歷屬性值產(chǎn)生結(jié)果鱼辙,則移除移動(dòng)器廉嚼。

gremlin> g.V().hasLabel('person')
==>v[1]
==>v[2]
==>v[4]
==>v[6]
gremlin> g.V().hasLabel('person').out().has('name',within('vadas','josh'))
==>v[2]
==>v[4]
gremlin> g.V().hasLabel('person').out().has('name',within('vadas','josh')).
               outE().hasLabel('created')
==>e[10][4-created->5]
==>e[11][4-created->3]
gremlin> g.V().has('age',inside(20,30)).values('age') //1.查找年齡在20(含)和30(不含)之間的所有頂點(diǎn)。
==>29
==>27
gremlin> g.V().has('age',outside(20,30)).values('age') //2.查找年齡不在20(含)和30(不含)之間的所有頂點(diǎn)倒戏。
==>32
==>35
gremlin> g.V().has('name',within('josh','marko')).valueMap() //3.查找名稱完全匹配集合中任何名稱的所有頂點(diǎn)[josh,marko]怠噪,顯示這些頂點(diǎn)的所有鍵和值對(duì)。
==>[name:[marko],age:[29]]
==>[name:[josh],age:[32]]
gremlin> g.V().has('name',without('josh','marko')).valueMap() //4.查找名稱不在集合中的所有頂點(diǎn)[josh,marko]杜跷,顯示這些頂點(diǎn)的所有鍵傍念,值對(duì)。對(duì)葛闷。
==>[name:[vadas],age:[27]]
==>[name:[lop],lang:[java]]
==>[name:[ripple],lang:[java]]
==>[name:[peter],age:[35]]
gremlin> g.V().has('name',not(within('josh','marko'))).valueMap() //5.和前面的例子一樣憋槐,使用noton within來(lái)保存without。
==>[name:[vadas],age:[27]]
==>[name:[lop],lang:[java]]
==>[name:[ripple],lang:[java]]
==>[name:[peter],age:[35]]
gremlin> g.V().properties().hasKey('age').value() //6.查找所有年齡屬性并發(fā)布其價(jià)值淑趾。
==>29
==>27
==>32
==>35
gremlin> g.V().hasNot('age').values('name') //7.查找所有沒(méi)有年齡屬性并發(fā)出其名稱的頂點(diǎn)阳仔。
==>lop
==>ripple

Id

  • 接受一個(gè)Element,并從中提取其標(biāo)識(shí)符扣泊。
gremlin> g.V().id()
==>1
==>2
==>3
==>4
==>5
==>6
gremlin> g.V(1).out().id().is(2)
==>2
gremlin> g.V(1).outE().id()
==>9
==>7
==>8
gremlin> g.V(1).properties().id()
==>0
==>1

Identity 恒定

  • This identity():是恒等函數(shù)近范,其中當(dāng)前對(duì)象映射到其自身嘶摊。
gremlin> g.V().identity()
==>v[1]
==>v[2]
==>v[3]
==>v[4]
==>v[5]
==>v[6]

Inject 注入

  • This inject():將對(duì)象任意插入到遍歷流中
gremlin> g.V(4).out().values('name').inject('daniel')
==>daniel
==>ripple
==>lop
gremlin> g.V(4).out().values('name').inject('daniel').map {it.get().length()}
==>6
==>6
==>3
gremlin> g.V(4).out().values('name').inject('daniel').map {it.get().length()}.path()
==>[daniel,6]
==>[v[4],v[5],ripple,6]
==>[v[4],v[3],lop,3]

Is 是

  • This is():過(guò)濾標(biāo)量值
gremlin> g.V().values('age').is(32)
==>32
gremlin> g.V().values('age').is(lte(30))
==>29
==>27
gremlin> g.V().values('age').is(inside(30, 40))
==>32
==>35
gremlin> g.V().where(__.in('created').count().is(1)).values('name') //1.查找只有一個(gè)貢獻(xiàn)者的項(xiàng)目。
==>ripple
gremlin> g.V().where(__.in('created').count().is(gte(2))).values('name') //2.查找有兩個(gè)或更多貢獻(xiàn)者的項(xiàng)目评矩。
==>lop
gremlin> g.V().where(__.in('created').values('age').
                                    mean().is(inside(30d, 35d))).values('name') //3.查找貢獻(xiàn)者平均年齡在30歲到35歲之間的項(xiàng)目叶堆。
==>lop
==>ripple

Key 鍵

  • This key():需要Property,并從中提取的關(guān)鍵斥杜。
gremlin> g.V(1).properties().key()
==>name
==>location
==>location
==>location
==>location
gremlin> g.V(1).properties().properties().key()
==>startTime
==>endTime
==>startTime
==>endTime
==>startTime
==>endTime
==>startTime

Label 標(biāo)簽

  • 需要一個(gè)Element并從中提取其標(biāo)簽虱颗。
gremlin> g.V().label()
==>person
==>person
==>software
==>person
==>software
==>person
gremlin> g.V(1).outE().label()
==>created
==>knows
==>knows
gremlin> g.V(1).properties().label()
==>name
==>age

Limit 限制

  • 類似于range()-步驟保存的下端范圍被設(shè)定為0。
gremlin> g.V().limit(2)
==>v[1]
==>v[2]
gremlin> g.V().range(0, 2)
==>v[1]
==>v[2]
  • 這個(gè)步驟limit()也可以應(yīng)用Scope.local蔗喂,在這種情況下忘渔,它在收到的收集上運(yùn)行。
gremlin> g.V().valueMap().select('location').limit(local,2) //1.List<String> 對(duì)于包含前兩個(gè)位置的每個(gè)頂點(diǎn)弱恒。
==>[san diego,santa cruz]
==>[centreville,dulles]
==>[bremen,baltimore]
==>[spremberg,kaiserslautern]
gremlin> g.V().valueMap().limit(local, 1) //2.Map<String, Object> 為每個(gè)頂點(diǎn)辨萍,但只包含第一個(gè)屬性值棋恼。
==>[name:[marko]]
==>[name:[stephen]]
==>[name:[matthias]]
==>[name:[daniel]]
==>[name:[gremlin]]
==>[name:[tinkergraph]]

Local 本地

  • A GraphTraversal在連續(xù)的對(duì)象流上運(yùn)行返弹。
  • 在很多情況下,在該流內(nèi)的單個(gè)元素上操作非常重要爪飘。為了做這種對(duì)象局部遍歷計(jì)算
gremlin> g.V().as('person').
               properties('location').order().by('startTime',incr).limit(2).value().as('location').
               select('person','location').by('name').by() //1.根據(jù)歷史最悠久的地點(diǎn)開(kāi)始時(shí)間獲取前兩個(gè)人和他們各自的位置义起。
==>[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() //2.對(duì)于每個(gè)人來(lái)說(shuō),他們的兩個(gè)最具歷史意義的地點(diǎn)
==>[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]

Loops 循環(huán)

  • This loops():提取的次數(shù)的數(shù)目Traverser已經(jīng)通過(guò)電流環(huán)路消失师崎。
remlin> g.V().emit(__.has("name", "marko").or().loops().is(2)).repeat(__.out()).values("name")
==>marko
==>ripple
==>lop

Match 匹配

  • 提供了一個(gè)更加聲明 基于的概念圖表查詢的形式圖案匹配默终。
  • 用戶提供了一組“遍歷碎片”,稱為模式犁罩,它們定義了必須在整個(gè)持續(xù)時(shí)間內(nèi)保持為真的變量match()齐蔽。
  • 當(dāng)一個(gè)遍歷器進(jìn)入時(shí)match(),一個(gè)注冊(cè) MatchAlgorithm分析遍歷器的當(dāng)前狀態(tài)(也就是基于其路徑數(shù)據(jù)的歷史 )床估,遍歷模式的運(yùn)行時(shí)統(tǒng)計(jì)信息含滴,并返回遍歷器應(yīng)該接下來(lái)嘗試的遍歷模式。
  • MatchAlgorithm提供的默認(rèn)值被調(diào)用CountMatchAlgorithm并且它通過(guò)根據(jù)模式的過(guò)濾能力對(duì)模式進(jìn)行排序來(lái)動(dòng)態(tài)修改模式執(zhí)行計(jì)劃(即丐巫,最大集合縮減模式首先執(zhí)行)谈况。
gremlin> g.V().match(
                 __.as('a').out('created').as('b'),
                 __.as('b').has('name', 'lop'),
                 __.as('b').in('created').as('c'),
                 __.as('c').has('age', 29)).
               select('a','c').by('name')
==>[a:marko,c:marko]
==>[a:josh,c:marko]
==>[a:peter,c:marko]
  • 為了提高可讀性,as()可以為步驟提供有意義的標(biāo)簽递胧,以更好地反映您的域名碑韵。因此,以前的查詢可以用更具表現(xiàn)力的方式編寫缎脾,如下所示祝闻。
gremlin> g.V().match(
                 __.as('creators').out('created').has('name', 'lop').as('projects'), //1.找到創(chuàng)建東西的頂點(diǎn)并將它們匹配為“創(chuàng)建者”,然后找出他們創(chuàng)建的名為“l(fā)op”并將這些頂點(diǎn)匹配為“項(xiàng)目”的頂點(diǎn)遗菠。
                 __.as('projects').in('created').has('age', 29).as('cocreators')). //2.使用這些'項(xiàng)目'頂點(diǎn)联喘,找出他們的創(chuàng)作者29歲屉栓,并記住這些'共同創(chuàng)作者'。
               select('creators','cocreators').by('name') //3.返回'創(chuàng)作者'和'共同創(chuàng)作者'的名字耸袜。
==>[creators:marko,cocreators:marko]
==>[creators:josh,cocreators:marko]
==>[creators:peter,cocreators:marko]
使用匹配的地方
  • 匹配通常與兩者select()(先前演示)和where()(在此展示)一起使用友多。
  • A- where()step允許用戶進(jìn)一步限制由提供的結(jié)果集match()。
gremlin> g.V().match(
                 __.as('a').out('created').as('b'),
                 __.as('b').in('created').as('c')).
                 where('a', neq('c')).
               select('a','c').by('name')
==>[a:marko,c:josh]
==>[a:marko,c:peter]
==>[a:josh,c:marko]
==>[a:josh,c:peter]
==>[a:peter,c:marko]
==>[a:peter,c:josh]
  • where()-步驟可以采取任一個(gè)P-predicate(例如上文)或一個(gè)Traversal(下面例子)堤框。使用時(shí) MatchPredicateStrategy域滥,where()-clauses自動(dòng)折疊match(),因此受制于查詢優(yōu)化器match()蜈抓。
gremlin> traversal = g.V().match(
                             __.as('a').has(label,'person'), //1\
                             __.as('a').out('created').as('b'),
                             __.as('b').in('created').as('c')).
                             where(__.as('a').out('knows').as('c')). //2\
                           select('a','c').by('name'); null //3\
gremlin> traversal.toString() //4\
==>[GraphStep(vertex,[]), MatchStep(AND,[[MatchStartStep(a), HasStep([~label.eq(person)]), MatchEndStep], [MatchStartStep(a), VertexStep(OUT,[created],vertex), MatchEndStep(b)], [MatchStartStep(b), VertexStep(IN,[created],vertex), MatchEndStep(c)]]), WhereTraversalStep([WhereStartStep(a), VertexStep(OUT,[knows],vertex), WhereEndStep(c)]), SelectStep(last,[a, c],[value(name)])]
gremlin> traversal // (5) 
==>[a:marko,c:josh]
gremlin> traversal.toString() //7\
==>[TinkerGraphStep(vertex,[~label.eq(person)])@[a], MatchStep(AND,[[MatchStartStep(a), VertexStep(OUT,[created],vertex), MatchEndStep(b)], [MatchStartStep(b), VertexStep(IN,[created],vertex), MatchEndStep(c)], [MatchStartStep(a), WhereTraversalStep([WhereStartStep, VertexStep(OUT,[knows],vertex), WhereEndStep(c)]), MatchEndStep]]), SelectStep(last,[a, c],[value(name)])]

Math

  • 科學(xué)計(jì)算器功能
gremlin> g.V().as('a').out('knows').as('b').math('a + b').by('age')
==>56.0
==>61.0
gremlin> g.V().as('a').out('created').as('b').
           math('b + a').
             by(both().count().math('_ + 100')).
             by('age')
==>132.0
==>133.0
==>135.0
==>138.0
gremlin> g.withSideEffect('x',10).V().values('age').math('_ / x')
==>2.9
==>2.7
==>3.2
==>3.5
gremlin> g.withSack(1).V(1).repeat(sack(sum).by(constant(1))).times(10).emit().sack().math('sin _')
==>0.9092974268256817
==>0.1411200080598672
==>-0.7568024953079282
==>-0.9589242746631385
==>-0.27941549819892586
==>0.6569865987187891
==>0.9893582466233818
==>0.4121184852417566
==>-0.5440211108893698
==>-0.9999902065507035
  • 通過(guò)計(jì)算器支持的運(yùn)營(yíng)商包括:*启绰,+,\沟使,^委可,和%。此外腊嗡,還提供了以下內(nèi)置功能:

    • abs: 絕對(duì)值

    • acos:反余弦

    • asin:反正弦

    • atan:反正切

    • cbrt:立方根

    • ceil:最接近的大整數(shù)

    • cos:余弦

    • cosh:雙曲余弦

    • exp:歐拉的號(hào)碼提升到了力量(e^x)

    • floor:最接近的較小整數(shù)

    • log:logarithmus naturalis(基數(shù)e)

    • log10:對(duì)數(shù)(基數(shù)10)

    • log2:對(duì)數(shù)(基數(shù)2)

    • sin:正弦

    • sinh:雙曲正弦

    • sqrt: 平方根

    • tan:切線

    • tanh:雙曲正切

    • signum:signum函數(shù)

Max

  • 最大值
gremlin> g.V().values('age').max()
==>35
gremlin> g.V().repeat(both()).times(3).values('age').max()
==>35

Mean 平均值

  • 操作數(shù)的流着倾,并確定這些數(shù)字的平均值。
gremlin> g.V().values('age').mean()
==>30.75
gremlin> g.V().repeat(both()).times(3).values('age').mean() //1\
==>30.645833333333332
gremlin> g.V().repeat(both()).times(3).values('age').dedup().mean()
==>30.75

Min 最小值

  • 操作數(shù)的流燕少,并確定它是在流中的最小數(shù)目卡者。
gremlin> g.V().values('age').min()
==>27
gremlin> g.V().repeat(both()).times(3).values('age').min()
==>27

Not

  • (過(guò)濾器時(shí)遍歷提供作為參數(shù)不返回任何對(duì)象)去除遍歷流對(duì)象。
gremlin> g.V().not(hasLabel('person')).valueMap(true)
==>[id:3,name:[lop],label:software,lang:[java]]
==>[id:5,name:[ripple],label:software,lang:[java]]
gremlin> g.V().hasLabel('person').
           not(out('created').count().is(gt(1))).values('name') //1.喬什創(chuàng)建了兩個(gè)項(xiàng)目客们,而沒(méi)有任何項(xiàng)目
==>marko
==>vadas
==>peter

Option

  • An option to a branch() or choose().

Optional

  • 如果它產(chǎn)生的結(jié)果崇决,否則返回調(diào)用元件
  • 返回指定遍歷的結(jié)果identity()。
gremlin> g.V(2).optional(out('knows')) //1.vadas沒(méi)有離開(kāi)的知識(shí)邊緣底挫,所以vadas被返回恒傻。
==>v[2]
gremlin> g.V(2).optional(__.in('knows')) //2.vadas確實(shí)有一個(gè)傳入知識(shí)邊緣,所以marko被返回建邓。
==>v[1]

Or 或者

  • This or():確保了提供遍歷中的至少一個(gè)產(chǎn)生的結(jié)果
gremlin> g.V().or(
            __.outE('created'),
            __.inE('created').count().is(gt(1))).
              values('name')
==>marko
==>lop
==>josh
==>peter
  • 一個(gè)中間符號(hào)可以被使用盈厘。盡管用中綴表示法,只有兩次遍歷可以在一起涝缝。
gremlin> g.V().where(outE('created').or().outE('knows')).values('name')
==>marko
==>josh
==>peter

Order 排序

  • 當(dāng)遍歷流的對(duì)象需要排序時(shí)
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().hasLabel('person').order().by('age', incr).values('name')
==>vadas
==>marko
==>josh
==>peter
  • 遍歷中最遍歷的對(duì)象之一是Element扑庞。元素可以具有與其關(guān)聯(lián)的屬性(即鍵/值對(duì))。在許多情況下拒逮,需要根據(jù)元素屬性的比較對(duì)元素遍歷流進(jìn)行排序罐氨。
gremlin> g.V().values('name')
==>marko
==>vadas
==>lop
==>josh
==>ripple
==>peter
gremlin> g.V().order().by('name',incr).values('name')
==>josh
==>lop
==>marko
==>peter
==>ripple
==>vadas
gremlin> g.V().order().by('name',decr).values('name')
==>vadas
==>ripple
==>peter
==>marko
==>lop
==>josh
  • 可以用來(lái)order(local)排序當(dāng)前的本地對(duì)象,而不是整個(gè)遍歷流滩援。這適用于 Collection- 和Map- 類型的對(duì)象栅隐。對(duì)于任何其他對(duì)象,該對(duì)象將保持不變。
gremlin> g.V().values('age').fold().order(local).by(decr) //1租悄。年齡被收集到一個(gè)列表中谨究,然后該列表按降序排列。
==>[35,32,29,27]
gremlin> g.V().values('age').order(local).by(decr) //2泣棋。年齡不收集胶哲,因此order(local)是“排序”單個(gè)整數(shù),因此潭辈,什么都不做鸯屿。
==>29
==>27
==>32
==>35
gremlin> g.V().groupCount().by(inE().count()).order(local).by(values, decr) //3。該groupCount()地圖是由它的遞減順序值進(jìn)行排序把敢。
==>[1:3,0:2,3:1]
gremlin> g.V().groupCount().by(inE().count()).order(local).by(keys, incr) //4寄摆。該groupCount()圖是通過(guò)其在遞增的順序排列的鍵。
==>[0:2,1:3,3:1]

Path 路徑

  • 遍歷器在遍歷中的一系列步驟中進(jìn)行轉(zhuǎn)換修赞。遍歷器的歷史通過(guò)用path()-step(地圖)檢查其路徑來(lái)實(shí)現(xiàn)婶恼。
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]
  • 可以通過(guò)循環(huán)方式后處理路徑的元素by()。
gremlin> g.V().out().out().path().by('name').by('age')
==>[marko,32,ripple]
==>[marko,32,lop]

Profile

  • 為了讓開(kāi)發(fā)者介紹他們的遍歷柏副,以確定像步運(yùn)行勾邦,計(jì)數(shù)等統(tǒng)計(jì)信息
gremlin> g.V().out('created').repeat(both()).times(3).hasLabel('person').values('age').sum().profile()
==>Traversal Metrics
Step                                                               Count  Traversers       Time (ms)    % Dur
=============================================================================================================
TinkerGraphStep(vertex,[])                                             6           6           0.076    11.61
VertexStep(OUT,[created],vertex)                                       4           4           0.108    16.39
NoOpBarrierStep(2500)                                                  4           2           0.050     7.63
VertexStep(BOTH,vertex)                                               10           4           0.045     6.86
NoOpBarrierStep(2500)                                                 10           3           0.025     3.81
VertexStep(BOTH,vertex)                                               24           7           0.028     4.34
NoOpBarrierStep(2500)                                                 24           5           0.030     4.62
VertexStep(BOTH,vertex)                                               58          11           0.040     6.15
NoOpBarrierStep(2500)                                                 58           6           0.046     7.03
HasStep([~label.eq(person)])                                          48           4           0.033     5.08
PropertiesStep([age],value)                                           48           4           0.042     6.37
SumGlobalStep                                                          1           1           0.133    20.11
                                            >TOTAL                     -           -           0.662        -

Project

  • 突出的當(dāng)前對(duì)象到Map
gremlin> g.V().out('created').
           project('a','b').
             by('name').
             by(__.in('created').count()).
           order().by(select('b'),decr).
           select('a')
==>lop
==>lop
==>lop
==>ripple
gremlin> g.V().has('name','marko').
                        project('out','in').
                          by(outE().count()).
                          by(inE().count())
==>[out:3,in:0]

Program

  • 是“l(fā)ambda”步驟GraphComputer的作業(yè)。

  • 該步驟將 VertexProgram作為參數(shù)并相應(yīng)地處理傳入圖搓扯。

  • 因此检痰,用戶可以創(chuàng)建自己的VertexProgram并在遍歷中執(zhí)行它包归。提供給頂點(diǎn)程序的配置包括:

    • gremlin.vertexProgramStep.rootTraversal是PureTraversal根遍歷的一種形式的序列化锨推。

    • gremlin.vertexProgramStep.stepId是program()正在執(zhí)行的-step 的步驟字符串id 。

gremlin> g = graph.traversal().withComputer()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], graphcomputer]
gremlin> g.V().hasLabel('person').
           program(PageRankVertexProgram.build().property('rank').create(graph)).
             order().by('rank', incr).
           valueMap('name', 'rank')
==>[name:[marko],rank:[0.11375510357865541]]
==>[name:[peter],rank:[0.11375510357865541]]
==>[name:[vadas],rank:[0.14598540152719106]]
==>[name:[josh],rank:[0.14598540152719106]]

Properties 屬性

  • 提取屬性Element遍歷流公壤。
gremlin> g.V(1).properties()
==>vp[name->marko]
==>vp[location->san diego]
==>vp[location->santa cruz]
==>vp[location->brussels]
==>vp[location->santa fe]
gremlin> g.V(1).properties('location').valueMap()
==>[startTime:1997,endTime:2001]
==>[startTime:2001,endTime:2004]
==>[startTime:2004,endTime:2005]
==>[startTime:2005]
gremlin> g.V(1).properties('location').has('endTime').valueMap()
==>[startTime:1997,endTime:2001]
==>[startTime:2001,endTime:2004]
==>[startTime:2004,endTime:2005]

PropertyMap

  • 步驟產(chǎn)生一個(gè)元素的屬性的地圖表示
gremlin> g.V().propertyMap()
==>[name:[vp[name->marko]],age:[vp[age->29]]]
==>[name:[vp[name->vadas]],age:[vp[age->27]]]
==>[name:[vp[name->lop]],lang:[vp[lang->java]]]
==>[name:[vp[name->josh]],age:[vp[age->32]]]
==>[name:[vp[name->ripple]],lang:[vp[lang->java]]]
==>[name:[vp[name->peter]],age:[vp[age->35]]]
gremlin> g.V().propertyMap('age')
==>[age:[vp[age->29]]]
==>[age:[vp[age->27]]]
==>[]
==>[age:[vp[age->32]]]
==>[]
==>[age:[vp[age->35]]]
gremlin> g.V().propertyMap('age','blah')
==>[age:[vp[age->29]]]
==>[age:[vp[age->27]]]
==>[]
==>[age:[vp[age->32]]]
==>[]
==>[age:[vp[age->35]]]
gremlin> g.E().propertyMap()
==>[weight:p[weight->0.5]]
==>[weight:p[weight->1.0]]
==>[weight:p[weight->0.4]]
==>[weight:p[weight->1.0]]
==>[weight:p[weight->0.4]]
==>[weight:p[weight->0.2]]

Range

  • This range():當(dāng)遍歷器通過(guò)遍歷傳播時(shí)换可,可能只允許一定數(shù)量的它們通過(guò).
  • 當(dāng)范圍的低端不符合時(shí),對(duì)象繼續(xù)迭代厦幅。在低(包含)和高(獨(dú)占)范圍內(nèi)沾鳄,發(fā)射移動(dòng)器。當(dāng)在高范圍以上時(shí)确憨,遍歷就會(huì)脫離迭代译荞。最后,-1高范圍的使用將在低范圍開(kāi)始后發(fā)射剩余的移動(dòng)器休弃。
gremlin> g.V().range(0,3)
==>v[1]
==>v[2]
==>v[3]
gremlin> g.V().range(1,3)
==>v[2]
==>v[3]
gremlin> g.V().range(1, -1)
==>v[2]
==>v[3]
==>v[4]
==>v[5]
==>v[6]
gremlin> g.V().repeat(both()).times(1000000).emit().range(6,10)
==>v[1]
==>v[5]
==>v[3]
==>v[1]
  • range()也可以應(yīng)用Scope.local吞歼,在這種情況下,它在收到的收集上運(yùn)行塔猾。例如篙骡,可以Map
gremlin> g.V().as('a').out().as('b').in().as('c').select('a','b','c').by('name').range(local,1,2)
==>[b:lop]
==>[b:lop]
==>[b:lop]
==>[b:vadas]
==>[b:josh]
==>[b:ripple]
==>[b:lop]
==>[b:lop]
==>[b:lop]
==>[b:lop]
==>[b:lop]
==>[b:lop]

Repeat

  • 用于遍歷給予一定的休息謂詞遍歷。
gremlin> g.V(1).repeat(out()).times(2).path().by('name') //1.do-while semantics stating to do out() 2 times.
==>[marko,josh,ripple]
==>[marko,josh,lop]
gremlin> g.V().until(has('name','ripple')).
               repeat(out()).path().by('name') //2.while-do語(yǔ)義如果遍歷器位于名為“ripple”的頂點(diǎn),則聲明為中斷糯俗。
==>[marko,josh,ripple]
==>[josh,ripple]
==>[ripple]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末尿褪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子得湘,更是在濱河造成了極大的恐慌杖玲,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淘正,死亡現(xiàn)場(chǎng)離奇詭異天揖,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)跪帝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門今膊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人伞剑,你說(shuō)我怎么就攤上這事斑唬。” “怎么了黎泣?”我有些...
    開(kāi)封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵恕刘,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我抒倚,道長(zhǎng)褐着,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任托呕,我火速辦了婚禮含蓉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘项郊。我一直安慰自己馅扣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布着降。 她就那樣靜靜地躺著差油,像睡著了一般。 火紅的嫁衣襯著肌膚如雪任洞。 梳的紋絲不亂的頭發(fā)上蓄喇,一...
    開(kāi)封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音交掏,去河邊找鬼妆偏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛耀销,可吹牛的內(nèi)容都是我干的楼眷。 我是一名探鬼主播铲汪,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼罐柳!你這毒婦竟也來(lái)了掌腰?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤张吉,失蹤者是張志新(化名)和其女友劉穎齿梁,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體肮蛹,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡勺择,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伦忠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片省核。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖昆码,靈堂內(nèi)的尸體忽然破棺而出气忠,到底是詐尸還是另有隱情,我是刑警寧澤赋咽,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布旧噪,位于F島的核電站,受9級(jí)特大地震影響脓匿,放射性物質(zhì)發(fā)生泄漏淘钟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一陪毡、第九天 我趴在偏房一處隱蔽的房頂上張望米母。 院中可真熱鬧,春花似錦缤骨、人聲如沸爱咬。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至燎斩,卻和暖如春虱歪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背栅表。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工笋鄙, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人怪瓶。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓萧落,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子找岖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容