Gremlin:圖遍歷語言

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

Gremlin簡(jiǎn)介

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

Gremlin包括三個(gè)基本的操作:

  • map-step
    對(duì)數(shù)據(jù)流中的對(duì)象進(jìn)行轉(zhuǎn)換;
  • filter-step
    對(duì)數(shù)據(jù)流中的對(duì)象就行過濾;
  • sideEffect-step
    對(duì)數(shù)據(jù)流進(jìn)行計(jì)算統(tǒng)計(jì);

以下是Gremlin在一些場(chǎng)景中的具體應(yīng)用:

  • 1.查找Gremlin朋友的朋友
g.V().has("name","gremlin").
  out("knows").
  out("knows").
  values("name")
  • 2.查找那些由兩個(gè)朋友共同創(chuàng)建的項(xiàng)目
g.V().match(
  as("a").out("knows").as("b"),
  as("a").out("created").as("c"),
  as("b").out("created").as("c"),
  as("c").in("created").count().is(2)).
    select("c").by("name")
  • 3.給出Gremlin的所有上司,直至CEO
g.V().has("name","gremlin").
  repeat(in("manages")).
    until(has("title","ceo")).
  path().by("name")
  • 4.獲得Gremlin合作者的頭銜分布
g.V().has("name","gremlin").as("a").
  out("created").in("created").
    where(neq("a")).
  groupCount().by("title")
  • 5.獲取Gremlin購(gòu)買產(chǎn)品的相關(guān)產(chǎn)品列表并排序
g.V().has("name","gremlin").
  out("bought").aggregate("stash").
  in("bought").out("bought").
    where(not(within("stash"))).
  groupCount().order(local).by(values,decr)
  • 6.獲取排名前十的中心人物
g.V().hasLabel("person").
  pageRank().
    by("friendRank").
    by(outE("knows")).
  order().by("friendRank",decr).
  limit(10)

OLTP 和 OLAP遍歷

  • 一次編寫,到處運(yùn)行
    Gremlin遵循“一次編寫,到處運(yùn)行”的設(shè)計(jì)哲學(xué)。這意味著不僅所有的TinkerPop啟用的圖形系統(tǒng)都能執(zhí)行Gremlin遍歷,而且每個(gè)Gremlin遍歷都可以被評(píng)估為實(shí)時(shí)數(shù)據(jù)庫(kù)查詢或批處理查詢。(前者被稱為在線交易流程(OLTP),后者被稱為在線分析流程(OLAP))。

  • 協(xié)調(diào)多種圖遍歷
    這種普遍性是由Gremlin遍歷機(jī)實(shí)現(xiàn)的。這種分布式、基于圖形的虛擬機(jī)了解如何協(xié)調(diào)多機(jī)器圖遍歷的執(zhí)行。好處是,用戶不需要學(xué)習(xí)數(shù)據(jù)庫(kù)查詢語言和域特定的BigData分析語言(例如Spark DSL,MapReduce等)。Gremlin是構(gòu)建基于圖的應(yīng)用程序所必要的,其余一切都交給Gremlin遍歷機(jī)處理。

image

命令式和聲明式遍歷

Gremlin遍歷可以以命令式(程序式)方式,聲明性(描述性)方式編寫,也可以包含命令性和聲明性的混合方式編寫。

  • 命令式編寫方式
    獲得Gremlin合作者的上司名字分布:
g.V().has("name","gremlin").as("a").
  out("created").in("created").
    where(neq("a")).
  in("manages").
  groupCount().by("name")

一個(gè)命令式的Gremlin遍歷告訴運(yùn)行器如何執(zhí)行遍歷中的每一步;然后,遍歷器分裂到所有的“Gremlin”的合作者(去除Gremlin自己);下一步,遍歷器走到“Gremlin”合作者的上司(managers),最終根據(jù)上司的名字進(jìn)行統(tǒng)計(jì)分發(fā)。

之所以是命令式的Gremlin遍歷,就是它明確地、程序化地告訴遍歷器“去這里,然后去那里”。

  • 聲明式編寫方式
    以下使用聲明式編寫方式實(shí)現(xiàn)了同樣的結(jié)果:
g.V().match(
  as("a").has("name","gremlin"),
  as("a").out("created").as("b"),
  as("b").in("created").as("c"),
  as("c").in("manages").as("d"),
    where("a",neq("c"))).
  select("d").
  groupCount().by("name")

聲明式的Gremlin遍歷并不能告訴遍歷器執(zhí)行它們的步驟的順序,而是允許每個(gè)遍歷器從一個(gè)(可能嵌套的)模式的集合中選擇一個(gè)模式來執(zhí)行。

然而,聲明遍歷具有額外的好處,它不僅利用了編譯時(shí)查詢計(jì)劃器(如命令式遍歷),而且還是一個(gè)運(yùn)行時(shí)查詢計(jì)劃器,根據(jù)每個(gè)模式的歷史統(tǒng)計(jì)信息選擇下一個(gè)執(zhí)行哪個(gè)遍歷模式 - 有利于那些傾向于減少/過濾大多數(shù)數(shù)據(jù)的模式。

用戶可以選擇上述提出的方式編寫自己的遍歷語句。不管怎樣,用戶的遍歷語句都會(huì)根據(jù)具體的執(zhí)行引擎和遍歷策略traversal strategies被重寫。Gremlin為用戶提供靈活性表達(dá)自己的查詢的;圖系統(tǒng)也針對(duì)具體啟用TinkerPop的數(shù)據(jù)系統(tǒng)進(jìn)行有效地評(píng)估圖遍歷提供了靈活性。

無縫嵌入主語言

  • 統(tǒng)一主開發(fā)語言和圖查詢語言
    經(jīng)典數(shù)據(jù)庫(kù)查詢語言(如SQL)被認(rèn)為與最終在生產(chǎn)環(huán)境中使用的編程語言截然不同。因此,經(jīng)典數(shù)據(jù)庫(kù)要求開發(fā)人員既要編寫主編程語言,還要編寫數(shù)據(jù)庫(kù)相應(yīng)的查詢語言。Gremlin統(tǒng)一了這個(gè)劃分,因?yàn)楸闅v可以用支持功能組合和嵌套(主要編程語言都支持)的任何編程語言編寫。因此,用戶的Gremlin遍歷可以使用應(yīng)用程序語言(主語言,Host language)編寫,并受益于主語言及其工具(例如類型檢查,語法高亮,點(diǎn)完成等)所提供的優(yōu)點(diǎn)。目前存在各種Gremlin語言變體,包括:Gremlin-Java,Gremlin-Groovy,Gremlin-Python,Gremlin-Scala等。

  • 示例程序
    比較以下兩種方式,高低立判:

public class GremlinTinkerPopExample {
  public void run(String name, String property) {

    Graph graph = GraphFactory.open(...);
    GraphTraversalSource g = graph.traversal();

    double avg = g.V().has("name",name).
                   out("knows").out("created").
                   values(property).mean().next();

    System.out.println("Average rating: " + avg);
  }
}
public class SqlJdbcExample {
  public void run(String name, String property) {

    Connection connection = DriverManager.getConnection(...)
    Statement statement = connection.createStatement();
    ResultSet result = statement.executeQuery(
      "SELECT AVG(pr." + property + ") as AVERAGE FROM PERSONS p1" +
        "INNER JOIN KNOWS k ON k.person1 = p1.id " +
        "INNER JOIN PERSONS p2 ON p2.id = k.person2 " +
        "INNER JOIN CREATED c ON c.person = p2.id " +
        "INNER JOIN PROJECTS pr ON pr.id = c.project " +
          "WHERE p.name = '" + name + "');

    System.out.println("Average rating: " + result.next().getDouble("AVERAGE")
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 甲圖是一個(gè)構(gòu)成的結(jié)構(gòu)的頂點(diǎn)和邊緣。頂點(diǎn)和邊都可以有任意數(shù)量的鍵/值對(duì)稱為屬性。頂點(diǎn)表示離散對(duì)象,例如人,地點(diǎn)或事件...
    達(dá)微閱讀 3,360評(píng)論 0 8
  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說明:當(dāng)在唯一索引所對(duì)應(yīng)的列上鍵入重復(fù)值時(shí),會(huì)觸發(fā)此異常。 O...
    我想起個(gè)好名字閱讀 5,970評(píng)論 0 9
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,712評(píng)論 0 5
  • TITLE: 編程語言亂燉 碼農(nóng)最大的煩惱——編程語言太多。不是我不學(xué)習(xí),這世界變化快! 有時(shí)候還是蠻懷念十幾、二...
    碼園老農(nóng)閱讀 5,593評(píng)論 2 35
  • 69【旅行】旅行的意義 放松,觀世界or世界觀,提要求,動(dòng)力 一個(gè)人生活的廣度表現(xiàn)ta優(yōu)秀的深度。 一切都有可能。
    依盈閱讀 152評(píng)論 0 0

友情鏈接更多精彩內(nèi)容