Gremlin-官網介紹翻譯

yoylee_web發表於2018-12-01

一:簡介

本博文為翻譯自官網的博文,官網:http://tinkerpop.apache.org/gremlin.html

Gremlin是Apache TinkerPop 框架下的圖遍歷語言,而TinkerPop是JanusGraph的搜尋引擎。Gremlin是一種函式式資料流語言,可以使得使用者使用簡潔的方式表述複雜的屬性圖(property graph)的遍歷或查詢。

每個Gremlin遍歷由一系列步驟(可能存在巢狀)組成,每一步都在資料流(data stream)上執行一個原子操作。每個步驟都是map -step(轉換流中的物件),filter -step(從流中刪除物件)或sideEffect-step(計算有關流的統計資訊)。Gremlin操作庫擴充套件了這些3基本操作,為使用者提供了豐富的step,使用者可以編寫這些step,以便更加靈活的獲取所需要的資料。

二:demo體驗

1:獲取Gremlin的朋友的朋友的名字

g.V().has("name","gremlin").          
  out("knows"). 
  out("knows").
  values("name")

步驟:1. 獲取名為“gremlin”的頂點。
2. 得到gremlin知道的人。
3. 遍歷那些人都知道的人。
4. 得到那些人的名字。

2:被兩位是朋友關係的人建立的專案名稱

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")

步驟:1. 建立匹配規則:存在a與b的認識關係。
2. 存在a創造了c。
3. 存在b創造了c。
4. 存在c被建立的關係的個數為2。
5. 根據匹配規則,獲取所有匹配的“c”專案的名稱。

3:獲取gremlin使用者的所有管理者的名字直到ceo

g.V().has("name","gremlin").
  repeat(in("manages")).
    until(has("title","ceo")).
  path().by("name")

步驟:1.找到gremlin節點
2.遍歷查詢gremlin的被管理關係
3.直到查詢到的節點包含title為ceo的節點為止
4.在遍歷路徑中的管理者姓名

4:獲取gremlin使用者的不同領域的合作者的title和其數量

g.V().has("name","gremlin").as("a").
  out("created").in("created").
    where(neq("a")).
  groupCount().by("title")

步驟:1.獲取gremlin使用者頂點並將該頂點設定為a,則下面的a便代表gremlin這個頂點
2.找到gremlin創造的專案,並且建立這些專案的人。得到的結果就是a和a的合作者
3.去除a,只剩下的a的合作者
4.通過title進行聚合計數,獲得最終結果

5:獲取gremlin購買的相關產品的的排名列表

g.V().has("name","gremlin").
    out("bought").aggregate("stash").
    in("bought").out("bought").
        where(not(within("stash")))order().by("friendRank",desc).
    groupCount().order(local).by(values,desc)

步驟:1. 獲取名為“gremlin”的頂點
2. 獲取Gremlin購買的產品並儲存為以“stash”命名的臨時集合
3. 還有誰買了這些產品,並且得到他們買的東西
4. 對結果集去除Gremlin購買的
5. 按照分組的結果進行降序排序

6:在知識圖中獲取10個最核心的人

g.V().hasLabel("person").
  pageRank().
    by("friendRank").
    by(outE("knows")).
  order().by("friendRank",desc).
  limit(10)

步驟:1. 獲取所有”人“的頂點
2. 使用know-edges計算他們的PageRank。
3. 通過他們的朋友排名得分。
4. 獲得排名前10位的人。
//pageRank()是google發明的頁面排名演算法,要想使用,必須這樣建立g = graph.traversal().withComputer()

三:OLTP 和 OLAP遍歷

Gremlin遵循“一次編寫,到處執行”的設計哲學。這意味著不僅所有的TinkerPop啟用的圖形系統都能執行Gremlin遍歷,而且每個Gremlin遍歷都可以被評估為實時資料庫查詢或批處理查詢。前者被稱為線上交易流程(OLTP),後者被稱為線上分析流程(OLAP)。

這主要得益於Gremlin traversal machine(Gremlin遍歷機)。這種分散式、基於圖形的虛擬機器瞭解如何協調多機器圖遍歷的執行。這樣做的好處是使用者不需要學習資料庫查詢語言和域特定的BigData分析語言(例如Spark DSL,MapReduce等)。Gremlin是構建基於圖的應用程式所必要的,其餘一切都交給Gremlin遍歷機處理。
在這裡插入圖片描述

四:命令式和宣告式遍歷

Gremlin遍歷可以以命令式(程式式)方式,宣告性(描述性)方式編寫,也可以包含命令性和宣告性的混合方式編寫。
命令式的Gremlin遍歷告訴遍歷者如何在遍歷中的每一步進行。

例如,下面的命令遍歷首先將遍歷器放置在表示Gremlin的頂點處。 然後那個將自己分裂到Gremlin的所有合作者身上,而這些合作者並不是Gremlin本人。 接下來,遍歷者獲取這些協作者的管理者,最終被分組為經理姓名計數分佈。

這種遍歷以明確的程式方式告訴遍歷者“去這裡然後去那裡”。

g.V().has("name","gremlin").as("a").
  out("created").in("created").
    where(neq("a")).
  in("manages").
  groupCount().by("name")

宣告式Gremlin遍歷並不告訴遍歷者執行其遍歷的順序,而是允許每個遍歷器從一組(可能巢狀的)模式中選擇要執行的模式。

下面的宣告式遍歷產生與上面的命令式遍歷相同的結果。

但是,宣告式遍歷還有一個額外的好處,即它不僅利用編譯時查詢計劃程式(如命令式遍歷),而且還利用執行時查詢計劃程式,根據每個模式的歷史統計資訊選擇接下來要執行的遍歷模式 - 支援那些傾向於 reduce/filter大多數資料的模式。

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")

使用者可以選擇的以任何方式編寫遍歷。當語句被編譯時,取決於底層執行引擎(即OLTP圖形資料庫或OLAP圖形處理器),使用者的遍歷由一組遍歷策略重寫,這些策略盡最大努力基於對圖資料訪問成本的理解以及底層資料系統的獨特功能(例如,從圖資料庫的“名稱” - 索引中獲取Gremlin頂點)確定最佳執行計劃 。Gremlin旨在為使用者提供表達查詢的靈活性,併為系統提供者提供如何有效評估針對其啟用TinkerPop的資料系統的遍歷的靈活性。

五:無縫嵌入主語言

經典資料庫查詢語言(如SQL)被認為與最終在生產環境中使用它們的程式語言有根本的不同。出於這個原因,經典資料庫要求開發人員以其本機程式語言以及資料庫的相應查詢語言進行編碼。“查詢語言”和“程式語言”之間的差異並不像我們所教導的那麼大。

Gremlin統一了這種鴻溝,遍歷可以用任何支援函式組合和巢狀的程式語言編寫(每種主要的程式語言都支援)。通過這種方式,使用者的Gremlin遍歷與其應用程式程式碼一起編寫,並受益於宿主語言及其工具提供的優勢(例如,型別檢查,語法突出顯示等)。存在各種Gremlin語言變體,包括:Gremlin-Java,Gremlin-Groovy,Gremlin-Python, Gremlin-Scala等。

下面的第一個示例顯示了一個簡單的Java類。請注意,Gremlin遍歷以Gremlin-Java表示,因此是使用者應用程式程式碼的一部分。遍歷嵌入在使用者的主機程式語言中,並與所有其他應用程式程式碼平等。

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);
  }}

使用Gremlin,使用者不必處理下面第二個例子中舉例說明的尷尬,這是整個行業中常見的反模式。

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")
  }}

在底層,Gremlin遍歷將針對嵌入式圖形資料庫進行本地評估,通過網路將自身序列化為遠端圖形資料庫,或將自身傳送到OLAP處理器以進行叢集範圍的分散式執行。遍歷源定義確定遍歷執行的位置,一旦定義了遍歷源,就可以以類似於資料庫連線的方式反覆使用它。最終的效果是使用者“感覺”他們的資料和遍歷都位於他們的應用程式中,並且可以通過他們的應用程式的本機程式語言訪問。“查詢語言/程式語言”-divide由Gremlin橋接。

六:更多的資訊

想要知道gremlin更多的用法,官網demo地址(特別詳細):http://kelvinlawrence.net/book/Gremlin-Graph-Guide.html#tpintro

相關文章