日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

复杂Gremlin查询的调试方法

發(fā)布時間:2024/1/1 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 复杂Gremlin查询的调试方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

復(fù)雜Gremlin查詢的調(diào)試方法

摘要:
Gremlin是圖數(shù)據(jù)庫查詢使用最普遍的基礎(chǔ)查詢語言。Gremlin的圖靈完備性,使其能夠編寫非常復(fù)雜的查詢語句。對于復(fù)雜的問題,我們該如何編寫一個復(fù)雜的查詢?以及我們該如何理解已有的復(fù)雜查詢?本文帶你逐步抽絲剝繭,完成復(fù)雜查詢的調(diào)試。

1. Gremlin簡介

Gremlin是Apache TinkerPop 框架下的圖遍歷語言。Gremlin是一種函數(shù)式數(shù)據(jù)流語言,可以使得用戶使用簡潔的方式表述復(fù)雜的屬性圖(property graph)的遍歷或查詢。每個Gremlin遍歷由一系列步驟(可能存在嵌套)組成,每一步都在數(shù)據(jù)流(data stream)上執(zhí)行一個原子操作。

Gremlin是一種用于描述屬性圖中行走的語言。圖形遍歷分兩個步驟進(jìn)行。

1.1. 遍歷源(TraversalSource)

開始節(jié)點(diǎn)選擇(Start node selection)。所有遍歷都從數(shù)據(jù)庫中選擇一組節(jié)點(diǎn)開始,這些節(jié)點(diǎn)充當(dāng)圖中行走的起點(diǎn)。
Gremlin中的遍歷是從TraversalSource開始的。 GraphTraversalSource提供了兩種遍歷方法。

  • GraphTraversalSource.V(Object … ids):從圖形的頂點(diǎn)開始遍歷(如果未提供id,則為所有頂點(diǎn))。
  • GraphTraversalSource.E(Object … ids):從圖形的邊緣開始遍歷(如果未提供id,則為所有邊)。

1.2. 圖遍歷(GraphTraversal)

走圖(Walking the graph)。從上一步中選擇的節(jié)點(diǎn)開始,遍歷會沿著圖形的邊行進(jìn),以根據(jù)節(jié)點(diǎn)和邊的屬性和類型到達(dá)相鄰的節(jié)點(diǎn)。遍歷的最終目標(biāo)是確定遍歷可以到達(dá)的所有節(jié)點(diǎn)。您可以將圖遍歷視為子圖描述,必須執(zhí)行該子圖描述才能返回節(jié)點(diǎn)。

V()和E()的返回類型是GraphTraversal。 GraphTraversal維護(hù)許多返回GraphTraversal的方法。GraphTraversal支持功能組合。 GraphTraversal的每種方法都稱為一個步驟(step),并且每個步驟都以五種常規(guī)方式之一調(diào)制(modulates)前一步驟的結(jié)果。

  • map:將傳入的遍歷對象轉(zhuǎn)換為另一個對象(S→E)。
  • flatMap:將傳入的遍歷對象轉(zhuǎn)換為其他對象的迭代器(S?E?S\subseteq E^*S?E?)。
  • filter:允許或禁止遍歷器進(jìn)行下一步(S→S∪?)。
  • sideEffect:允許遍歷器保持不變,但在過程中產(chǎn)生一些計算上的副作用(S?S)。
  • branch:拆分遍歷器并將其發(fā)送到遍歷中的任意位置(S→{S1→E?,…,Sn→E?S1→E^*,…,S_n→E^*S1E?Sn?E?}→E*)。
  • GraphTraversal中幾乎每個步驟都從MapStep,FlatMapStep,FilterStep,SideEffectStep或BranchStep擴(kuò)展得到。

    • 舉例:找到makro認(rèn)識的人
    gremlin> g.V().has('name','marko').out('knows').values('name') ==>vadas ==>josh

    1.3. Gremlin是圖靈完備的(Turing Complete)

    這也就時說任何復(fù)雜的問題,都可以用Gremlin描述。

    下面就調(diào)試和編寫復(fù)雜的gremlin查詢,給出指導(dǎo)思路和方法論。

    2. 復(fù)雜Gremlin查詢的調(diào)試

    Gremlin的查詢都是由簡單的查詢組合成復(fù)雜的查詢。所以對于復(fù)雜Gremlin查詢可以分為以下三個步驟,并逐步迭代完成所有語句的驗(yàn)證,此方法同樣適用編寫復(fù)雜的Gremlin查詢。

    2.1. 迭代調(diào)試步驟

  • 拆分分析步驟,劃大為小,逐步求證;
  • 輸出分步驟的結(jié)果,明確步驟的具體輸出內(nèi)容;
  • 對輸出結(jié)果進(jìn)行推導(dǎo)和檢驗(yàn)。擴(kuò)大或縮小分析步驟,回到步驟1繼續(xù),直到清楚所有結(jié)果。
    • 注:此方法參照Stephen Mallette gremlins-anatomy的分析邏輯和用例。

    2.2. 用例

    2.2.1. 圖結(jié)構(gòu)

    gremlin> graph = TinkerGraph.open() ==>tinkergraph[vertices:0 edges:0] gremlin> g = graph.traversal() ==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard] gremlin>g.addV().property('name','alice').as('a').addV().property('name','bobby').as('b').addV().property('name','cindy').as('c').addV().property('name','david').as('d').addV().property('name','eliza').as('e').addE('rates').from('a').to('b').property('tag','ruby').property('value',9).addE('rates').from('b').to('c').property('tag','ruby').property('value',8).addE('rates').from('c').to('d').property('tag','ruby').property('value',7).addE('rates').from('d').to('e').property('tag','ruby').property('value',6).addE('rates').from('e').to('a').property('tag','java').property('value',10).iterate() gremlin> graph ==>tinkergraph[vertices:5 edges:5]

    2.2.2. 查詢語句

    gremlin>g.V().has('name','alice').as('v').repeat(outE().as('e').inV().as('v')).until(has('name','alice')).store('a').by('name').store('a').by(select(all, 'v').unfold().values('name').fold()).store('a').by(select(all, 'e').unfold().store('x').by(union(values('value'), select('x').count(local)).fold()).cap('x').store('a').by(unfold().limit(local, 1).fold()).unfold().sack(assign).by(constant(1d)).sack(div).by(union(constant(1d),tail(local, 1)).sum()).sack(mult).by(limit(local, 1)).sack().sum()).cap('a') ==>[alice,[alice,bobby,cindy,david,eliza,alice],[9,8,7,6,10],18.833333333333332]

    好長,好復(fù)雜!

    看我如何抽絲剝繭,一步步驗(yàn)證結(jié)果。

    2.3. 調(diào)試過程

    2.3.1. 拆分查詢

    按執(zhí)行步驟,拆分成小的查詢,如下圖:

    • 執(zhí)行第一部分步驟
    gremlin> g.V().has('name','alice').as('v'). ......1> repeat(outE().as('e').inV().as('v')). ......2> until(has('name','alice')) ==>v[0]

    2.3.2. 澄清結(jié)果

    這里通過valueMap()輸出節(jié)點(diǎn)信息。

    gremlin> g.V().has('name','alice').as('v'). ......1> repeat(outE().as('e').inV().as('v')). ......2> until(has('name','alice')).valueMap() ==>[name:[alice]]

    2.3.3. 驗(yàn)證假設(shè)

    根據(jù)執(zhí)行語句的語義推導(dǎo)查詢過程,如下:

    使用path(), 驗(yàn)證推導(dǎo)過程

    g.V().has('name','alice').as('v'). ......1> repeat(outE().as('e').inV().as('v')). ......2> until(has('name','alice')).path().next() ==>v[0] ==>e[10][0-rates->2] ==>v[2] ==>e[11][2-rates->4] ==>v[4] ==>e[12][4-rates->6] ==>v[6] ==>e[13][6-rates->8] ==>v[8] ==>e[14][8-rates->0] ==>v[0]
    • 輸出結(jié)果與推導(dǎo)結(jié)果一致,擴(kuò)大查詢語句, 回到步驟1;
    • 如不一致或不理解結(jié)果, 縮小步驟范圍, 可以采用此步驟的上一層查詢步驟,回到步驟1;
    gremlin> g.V().has('name','alice').as('v'). ......1> repeat(outE().as('e').inV().as('v')). ......2> until(has('name','alice')). ......3> store('a').by('name') ==>v[0]
    • 如此循環(huán)直到完全理解整個查詢。

    大家可以自己去細(xì)細(xì)的剝下筍,此處略去3000字。

    3. 總結(jié)

    • 在分析的過程,采用劃分查詢語句的方法,分步理解,采用漏斗式的方法,逐步擴(kuò)大對語句的理解;
    • 對每步的查詢結(jié)果,可以采用利用valueMap(), path(), select(), as(), cap() 等函數(shù)輸出和驗(yàn)證結(jié)果;
    • 對于不清楚結(jié)果的步驟或與期望值不一致,縮小查詢步驟,可以采用輸出步驟的前一步驟作為輸出點(diǎn),進(jìn)行輸出和驗(yàn)證;
    • 對于上一層數(shù)據(jù)的結(jié)果明確的情況下,可以采用inject()方式注入上層輸出,繼續(xù)后續(xù)的輸出和驗(yàn)證;
    • 要注意步驟最后的函數(shù),對整個輸出結(jié)果的影響。

    4. 參考

    • Introduction to Gremlin
    • Gremlin’s Anatomy
    • TinkerPop Documentation
    • Stephen Mallette gremlins-anatomy
    • Practical Gremlin - Why Graph?

    總結(jié)

    以上是生活随笔為你收集整理的复杂Gremlin查询的调试方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。