<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文記錄了筆者摸索圖資料庫過程中遇到的問題、一些思考(閒談)與實現思路。
做此記錄的目的是沉澱經驗、完善鞏固知識體系,同時以此為始,培養撰寫文字、輸出內容的能力與習慣。
本文內容源自筆者自身見識,僅為一家之言,不足之處望諸位批評指正。
基於筆者當時的情況,對讀者做以下假設:
Apache TinkerPop™ is a graph computing framework for both graph databases (OLTP) and graph analytic systems (OLAP).
Apache TinkerPop 框架為圖資料庫 ( OLTP ) 和圖分析系統 ( OLAP ) 提供了一套標準的操作介面 Gremlin 。
GQL 之於圖資料庫,如同 SQL 之於關係型資料庫。在 GQL 標準落地之前,圖查詢語言的事實標準大概只有 Gremlin 與 Cypher,至於 Sparql ,僅支援 RDF 格式資料,不在更工程化的屬性圖模型討論範疇。
圖查詢語言 Gremlin 是 TinkerPop 框架為 圖服務使用者 ( User ) 提供的資料操作介面,而對於 圖服務提供商 ( Provider ) 來說,需要了解 TinkerPop 框架的屬性圖模型與介面。
TinkerPop 將其介面粗略劃分為 Structure 和 Process 兩部分。Structure 部分定義了圖的拓撲結構與功能,包括 Vertex、Edge、Property 等,由 圖服務提供商 ( Provider ) 實現其介面,以填充資料;Process 部分定義了遍歷圖資料的 DSL ,並提供呼叫 Structure 介面的預設實現。
作為剛接觸 TinkerPop 沒多久的 Provider,只需實現 Structure 介面即可完成 Gremlin 圖查詢功能的接入。
這也意味著沒有圖計算與事務功能,僅支援 Gremlin 查詢。
TinkerPop Provider 檔案中將 Provider 細分為:
本文中的 Provider 僅代表 Graph Database Provider 。
同樣地,Structure 介面僅包括 Gremlin-Core 模組 ( 原始碼 structure/ 資料夾下 ) 的下述介面:
圖 1 Structure 介面
Graph 介面在整個 Structure 體系中具有核心地位,是整個圖服務的入口與出口。
TinkerPop 的 Gremlin 執行過程依靠 Process 體系裡的各種類 ( TraversalSource, Strategy, Traversal, Step, Traverser, etc. ) 實現,最終呼叫 Graph 介面,從儲存層輸入輸出對應資料。
該介面作為圖遍歷的入口,在 Gremlin 指令碼執行過程中位於起始位置,從儲存層獲取資料後,交給後續操作執行進一步處理。
按照慣例,使用者將自己的 Graph 實現類命名為 XXXGraph,如官方樣例提供的 TinkerGraph、Neo4jGraph 等。
public final class TinkerGraph implements Graph {...} public final class Neo4jGraph implements Graph, WrappedGraph<Neo4jGraphAPI> {...}
又如 JanusGraph 原始碼中的 Graph 繼承體系:
// StandardJanusGraph 繼承 JanusGraphBlueprintsGraph public class StandardJanusGraph extends JanusGraphBlueprintsGraph {...} // JanusGraphBlueprintsGraph 實現 JanusGraph 介面 public abstract class JanusGraphBlueprintsGraph implements JanusGraph {...} // JanusGraph 介面繼承 Transaction 介面 public interface JanusGraph extends Transaction {...} // Transaction 介面繼承 Tinkerpop Graph 介面 public interface Transaction extends Graph, SchemaManager {...}
Tinkerpop Graph 介面提供了許多帶有預設實現的方法,僅留下如下幾個方法需要 Provider 自行實現:
新增節點方法 addVertex
Vertex addVertex(final Object... keyValues);
該方法對應著 g.addV() 與 graph.addVertex() 的呼叫方式,即為 Gremlin 語言 addV 功能提供支援。
實現思路為將傳入的引數處理為自己的 Vertex 介面實現類的物件,將該物件持久化到儲存層,並返回該物件。
獲取節點方法 vertices
Iterator<Vertex> vertices(final Object... vertexIds);
該方法支撐 Gremlin 語言 g.V() 呼叫。
實現思路為根據傳入的節點 ID 引數,到儲存層查詢節點資料,最終根據所查到的節點生成一個 Vertex 介面迭代器,並將其作為返回值。
獲取邊方法 edges
Iterator<Edge> edges(final Object... edgeIds);
該方法支撐 Gremlin 語言 g.E() 呼叫。
實現思路類似 vertices 方法。
圖退出方法 close
void close() throws Exception;
該方法提供了圖服務退出時,儲存持久化層與關閉事務等工作的呼叫勾子。
讀取使用者設定方法 variables 與 configuration
Variables variables();
Configuration configuration();
這倆方法可以隨意應付,不影響支撐 Gremlin 語言功能。
啟動事務方法 tx
Transaction tx();
可在實現中直接丟擲異常,表明該圖資料庫不支援事務功能,不影響支援 Gremlin 語言功能。
啟動圖計算方法 compute
GraphComputer compute() throws IllegalArgumentException;
實現思路類似事務。
屬性圖模型的基礎型別介面,Vertex、Edge、VertexProperty 均繼承該介面,表示圖中的元素。
命名慣例同 Graph 介面,實現類為 XXXElement。
該介面宣告了圖元素共有的屬性與方法,其中部分方法具有預設實現,需 Provider 自行實現的方法包括:
Object id();
圖元素唯一識別符號 id 的 Getter 方法。
此處 id 型別為 Object,但在具體實現時又會根據實際需要將 id 型別限制為數位或字串,又或是不限制型別。
String label();
圖元素標籤 label 的 Getter 方法。
標籤即為元素型別,在資料庫中被稱為 Meta,在知識圖譜中被稱為本體/概念。
TinkerPop 屬性圖模型似乎僅支援單標籤,而 Neo4j 屬性圖模型可支援多標籤,這點在 cypher-to-gremlin 專案的解析器中有所體現。
Graph graph();
圖元素所屬的圖範例的 Getter 方法。
此處暗示了 Element 實現類僅為記憶體中的物件,即資料庫中的外模式,並非持久層物件。因此,要在 Graph 介面實現類的 vertices()、edges()、addVertex() 中,為相應的圖元素設定 graph 屬性,供後續遍歷方法呼叫。
該方法支撐了其他關聯查詢介面,比如從已有圖元素出發,繼續查詢相關聯的節點或邊的方法。
g.V().has('person', 'name', 'marko').out("knows")
在該 Gremlin 語句中 g.V().has() 從 Graph 介面中獲得了起始節點,接著使用 out() 方法請求該節點的出邊關聯節點,而 out() 方法的實現中呼叫了該 graph() 方法。
此外,還需注意,對於一個圖資料庫來說,應該支援多個圖範例管理,這意味著同一個 Gremlin 語句,目標 graph 不同,得到的結果也不同,該方法返回的物件也是不同的。
<V> Property<V> property(final String key, final V value);
將屬性的 Key,Value 傳遞給當前圖元素。
實現思路為根據傳入的引數構建自己的 Property 物件,接著對圖元素的內模式做相應修改並持久化,最後返回該 Property 物件。
獲取屬性方法 properties
<V> Iterator<? extends Property<V>> properties(final String... propertyKeys);
根據傳入的屬性 Key 列表,從當前圖元素的屬性 Map 中過濾出相應的 Property 列表。
元素刪除方法 remove
void remove();
可在實現中丟擲異常,表示當前圖資料庫不支援刪除資料。
或者直接返回,假裝完成了刪除操作。
圖模型中的節點元素,該介面繼承 Element 介面,表示圖資料庫的節點外模式。
命名慣例同 Graph 介面,實現類為 XXXVertex,該類需繼承上述 XXXElement 類。
在介面設計上,TinkerPop 要求每個 Vertex 範例可以自身為起點,找到相關聯的入邊 ( Incoming Edges ) 和出邊 ( Outgoing Edges),以及連邊的另一端 Vertex 範例。
此設計天然適用於 無索引近鄰 式的圖處理結構。因此在實現 Vertex 介面時,可考慮在儲存層之上構建該處理結構,用以加速查詢。
該介面宣告了一些需要 Provider 實現的重要方法,這些方法在 Gremlin 查詢過程中起到了基石的作用。
新增出邊 addEdge
Edge addEdge(final String label, final Vertex inVertex, final Object... keyValues);
實現思路為根據傳入的邊標籤 label 和邊屬性 keyValues 構建 Edge 範例,並將其持久化。
如果實現了無索引近鄰結構,需進一步更新與該邊相關聯的兩點的索引內容。
如果實現了屬性索引,還需為相應屬性值與該 Edge 構建索引。
新增屬性 property
<V> VertexProperty<V> property(final VertexProperty.Cardinality cardinality, final String key, final V value, final Object... keyValues);
引數 cardinality 表示屬性基數,包括 single、list、set。
引數 key、value 無需多言。
此處需要理解 TinkerPop 中 VertexProperty 與 Property 的差異。
TinkerPop 將這種帶有屬性的屬性表示為 VertexProperty,歸屬於 Element。而僅有屬性值的屬性表示為 Property。VertexProperty 的屬性也是 Property 物件。
引數 keyValues 表示了該屬性的屬性,舉個例子:張三 ( Vertex ) 的學歷 ( Key ) 有小學、初中、高中 ( Value ),而每個學歷值都有入學時間、畢業時間、學校名稱等屬性 ( keyValues ) 。
奇怪的是,TinkerPop 將 Edge 的屬性表示為 Property,Property 物件沒有下一級屬性,這點可在 addEdge 方法與 Edge 介面中體會到。同時,與 Edge 有關的 Gremlin 處理步驟均無法設定屬性的屬性。
如此區分 Vertex 與 Edge 的屬性,總讓人覺得缺少對稱的美感,也不相容實際建模的需求。如果想要修改此行為,又將不可避免地入侵 TinkerPop 設計中未暴露介面的部分。若把屬性的屬性用 Map 儲存或序列化為字串作為 Edge 的屬性,似乎也有不少問題,至少在標準 Gremlin 語法上無法查詢 Edge 的屬性的屬性。
獲取相鄰邊 edges
Iterator<Edge> edges(final Direction direction, final String... edgeLabels);
實現思路:將引數中的方向和邊標籤作為過濾條件,從無索引近鄰結構或儲存層中查詢相關邊。
獲取相鄰節點 vertices
Iterator<Vertex> vertices(final Direction direction, final String... edgeLabels);
實現思路類似 edges 方法。
獲取節點屬性 properties
<V> Iterator<VertexProperty<V>> properties(final String... propertyKeys);
實現思路為從節點的詳細資訊中獲取屬性列表,然後根據引數 propertyKeys 過濾出對應屬性值。
圖模型中的邊元素,該介面繼承 Element 介面,表示圖資料庫的邊外模式。
命名慣例同 Graph 介面,實現類為 XXXEdge,該類需繼承上述 XXXElement 類。
在介面設計上,TinkerPop 要求每個 Edge 範例可以自身為起點,找到相關聯的起始節點和終止節點。
該介面提供了一些方法的預設實現,僅需 Provider 提供以下兩個方法的具體實現。
獲取相關節點 vertices
Iterator<Vertex> vertices(final Direction direction);
實現思路為根據當前 Edge 的資訊以及傳入的方向引數,從索引中獲儲存層查詢相關聯節點。
獲取相關屬性 properties
<V> Iterator<Property<V>> properties(final String... propertyKeys);
實現思路類似獲取節點屬性方法。
圖模型中的屬性元素,表示圖資料庫的屬性外模式。
命名慣例同 Graph 介面,實現類為 XXXProperty 。
A Property denotes a key/value pair associated with an Edge.
如上文討論的那樣,TinkerPop 在其檔案中明確寫道:屬性是與邊相關的 K/V 對,Key 只能是 String 型別,Value 只能是 Java 型別。
該介面提供了一些方法的預設實現,僅需 Provider 提供以下方法的具體實現。
獲取屬性鍵 key
String key();
該方法被呼叫時,往往已經獲取了 Provider 實現的 XXXProperty 物件,只需將該物件 key 值返回即可。
獲取屬性值 value
V value() throws NoSuchElementException;
實現思路同上。
獲取關聯物件 element
Element element();
實現思路同上。
判斷屬性值是否存在
boolean isPresent();
當前 XXXProperty 的 value 屬性非空時返回 true,否則返回 false。
刪除當前屬性 remove
void remove();
可在實現中丟擲異常,表示當前圖資料庫不支援刪除資料。
或者直接返回,假裝完成了刪除操作。
圖模型中的可攜帶屬性的節點屬性元素,表示圖資料庫的屬性外模式。
命名慣例同 Graph 介面,實現類為 XXXVertexProperty,該類需繼承 XXXElement 類。
A VertexProperty is similar to a Property in that it denotes a key/value pair associated with an Vertex, however it is different in the sense that it also represents an entity that it is an Element that can have properties of its own.
如上文討論的那樣,TinkerPop 在其檔案中明確寫道:節點屬性是與節點相關的 K/V 對,同時,節點屬性也是圖元素的一種,可以攜帶自己的屬性。
VertexProperty 介面提供了一些方法的預設實現,但由於該介面繼承了 Property 介面,因此需要 Provider 提供上述 Propery 介面方法和以下方法的具體實現。
獲取所屬節點 element
Vertex element();
該方法覆寫了 Property 介面的 element 方法,返回當前節點屬性所屬的 Vertex 物件。
獲取屬性 properties
<U> Iterator<Property<U>> properties(final String... propertyKeys);
返回當前節點屬性的屬性。
讀者可參照 TinkerPop 給的 TinkerGraph 原始碼和上一節所講的思路去嘗試實現自己的 Structure 體系。
圖 2 TinkerGraph Structure
當讀者完成上述實踐,成功在自己的 Graph 上執行 Gremlin 查詢後,需要認識到 TinkerGraph 中的圖資料全在記憶體中,沒有儲存層,查詢索引也不太正常,其結構與真實圖資料庫相比缺少代表性。
TinkerPop 原始碼中的另外幾個 Graph 實現例子,如 neo4jGraph、hadoopGraph 等,均有其各自的代表性,但仍不能覆蓋完整的圖資料庫功能。
想要了解更多圖資料庫實現細節,可通過閱讀 JanusGraph 、NebulaGraph (C++) 原始碼來學習相關知識。
以上就是TinkerPop框架查詢Gremlin圖實現過程詳解的詳細內容,更多關於TinkerPop框架查詢Gremlin圖的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45