久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

圖數據庫查詢語言Gremlin vs Cypher vs nGQL的操作入門是怎樣的

156次閱讀
沒有評論

共計 10677 個字符,預計需要花費 27 分鐘才能閱讀完成。

行業資訊    
數據庫    
圖數據庫查詢語言 Gremlin vs Cypher vs nGQL 的操作入門是怎樣的

圖數據庫查詢語言 Gremlin vs Cypher vs nGQL 的操作入門是怎樣的,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

文章的開頭我們先來看下什么是圖數據庫,根據維基百科的定義:圖數據庫是使用圖結構進行語義查詢的數據庫,它使用節點、邊和屬性來表示和存儲數據。

雖然和關系型數據庫存儲的結構不同(關系型數據庫為表結構,圖數據庫為圖結構),但不計各自的性能問題,關系型數據庫可以通過遞歸查詢或者組合其他 SQL 語句(Join)完成圖查詢語言查詢節點關系操作。得益于 1987 年 SQL 成為國際標準化組織(ISO)標準,關系型數據庫行業得到了很好的發展。同 60、70 年代的關系型數據庫類似,圖數據庫這個領域的查詢語言目前也沒有統一標準,雖然 19 年 9 月經過國際 SQL 標準委員會投票表決,決定將圖查詢語言(Graph Query Language)納為一種新的數據庫查詢語言,但 GQL 的制定仍需要一段時間。

介于市面上沒有統一的圖查詢語言標準,在本文中我們選取市面上主流的幾款圖查詢語言來分析一波用法,由于篇幅原因本文旨在簡單介紹圖查詢語言和常規用法,更詳細的內容將在進階篇中講述。

圖查詢語言·介紹圖查詢語言 Gremlin

Gremlin 是 Apache ThinkerPop 框架下的圖遍歷語言。Gremlin 可以是聲明性的也可以是命令性的。雖然 Gremlin 是基于 Groovy 的,但具有許多語言變體,允許開發人員以 Java、JavaScript、Python、Scala、Clojure 和 Groovy 等許多現代編程語言原生編寫 Gremlin 查詢。

支持圖數據庫:Janus Graph、InfiniteGraph、Cosmos DB、DataStax Enterprise(5.0+)    、Amazon Neptune

圖查詢語言 Cypher

Cypher 是一個描述性的圖形查詢語言,允許不必編寫圖形結構的遍歷代碼對圖形存儲有表現力和效率的查詢,和 SQL 很相似,Cypher 語言的關鍵字不區分大小寫,但是屬性值,標簽,關系類型和變量是區分大小寫的。

支持圖數據庫:Neo4j、RedisGraph、AgensGraph

圖查詢語言 nGQL

nGQL 是一種類 SQL 的聲明型的文本查詢語言,nGQL 同樣是關鍵詞大小寫不敏感的查詢語言,目前支持模式匹配、聚合運算、圖計算,可無嵌入組合語句。

支持圖數據庫:Nebula Graph

圖查詢語言·術語篇

在比較這 3 個圖查詢語言之前,我們先來看看他們各自的術語,如果你翻閱他們的文檔會經常見到下面這些“關鍵字”,在這里我們不講用法,只看這些圖數據庫常用概念在這 3 個圖數據庫文檔中的叫法。

術語 GremlinCyphernGQL 點 VertexNodeVertex 邊 EdgeRelationshipEdge 點類型 LabelLabelTag 邊類型 labelRelationshipTypeedge type 點 IDvidid(n)vid 邊 IDeidid(r) 無插入 addcreateinsert 刪除 dropdeletedelete / drop 更新屬性 setPropertysetupdate

我們可以看到大體上對點和邊的叫法類似,只不過 Cypher 中直接使用了 Relationship 關系一詞代表邊。其他的術語基本都非常直觀。

圖查詢語言·語法篇

了解過 Gremlin、Cypher、nGQL 中常見的術語之后,我們來看看使用這 3 個圖查詢語言過程中會需要了解的常規語法。

# Gremlin  創建圖
g = TinkerGraph.open().traversal()
# nGQL  創建圖空間
CREATE SPACE gods

圖結構由點和邊組成,一條邊連接兩個點。在 Gremlin 和 nGQL 中稱之為 Vertex,Cypher 則稱之為 Node。如何在圖數據庫中新建一個點呢?可以參考下面的語法

# Gremlin  創建 / 插入點
g.addV(vertexLabel).property()
# Cypher  創建點
CREATE (:nodeLabel {property})
# nGQL  創建 / 插入點
INSERT VERTEX tagName (propNameList) VALUES vid:(tagKey propValue)

點類型

點允許有對應的類型,在 Gremlin 和 Cypher 叫
label,在 nGQL 中為
tag。點類型可對應有多種屬性(Property),例如
Person 可以有
name、age 等屬性。

創建點類型

點類型相關的語法示例如下:

# Gremlin  創建點類型
g.addV(vertexLabel).property()
# nGQL  創建點類型
CREATE tagName(PropNameList)

這里說明下,無論在 Gremlin 和 nGQL 中存在類似
IF NOT EXISTS   用法,即:如果不存在則創建,存在則直接返回。

查看點類型

創建好點之后如何查看點類型呢,可以參考以下方式。

# Gremlin  查看(獲?。c類型
g.V().label().dedup();
# Cypher  查看點類型方法  1
MATCH (n) 
RETURN DISTINCT labels(n)
# Cypher  查看點類型方法  2
CALL db.labels();
# nGQL  查看點類型
SHOW TAGS

點的 CRUD

上面簡單介紹了點、點類型,下面進入數據庫基本 DML——CRUD,在上文介紹點時順便介紹了點的創建和插入,這里說下如何插入特定類型的點,和點的獲取、刪除和更新。

插入特定類型點

和插入點的操作類似,只不過需要指定某種點類型。語法參考:

# Gremlin  插入特定類型點
g.addV(String vertexLabel).property()
# Cypher  插入特定類型點
CREATE (node:label) 
# nGQL  插入特定類型點
INSERT VERTEX  tag_name  (prop_name_list) VALUES  vid :(prop_value_list)

查看點

# Gremlin  查看點
g.V(vid)
# Cypher  查看點
MATCH (n) 
WHERE condition
RETURN properties(n)
# nGQL  查看點
FETCH PROP ON  tag_name   vid

刪除點

術語篇中提過 nGQL 中刪除操作對應單詞有
Delete 和
Drop,在 nGQL 中 Delete 一般用于點邊,Drop 用于 Schema 刪除,這點和 SQL 的設計思路是一樣的。

# Gremlin  刪除點
g.V(vid).drop()
# Cypher  刪除點
MATCH (node:label) 
DETACH DELETE node
# nGQL  刪除點
DELETE VERTEX  vid

更新點

用數據庫的小伙伴都知道數據的常態是數據變更,來瞅瞅這 3 個圖查詢是使用什么語法來更新點數據的吧

# Gremlin  更新點
g.V(vid).property()
# Cypher  更新點
SET n.prop = V
# nGQL  更新點
UPDATE VERTEX  vid  SET  update_columns

可以看到 Cypher 和 nGQL 都使用 SET 關鍵詞來設置點對應的類型值,只不過 nGQL 中多了 UPDATE 關鍵詞來標識操作,Gremlin 的操作和上文提到的查看點類似,只不過增加了變更 property 值操作。

在 Gremlin 和 nGQL 稱呼邊為 Edge,而 Cypher 稱之為 Relationship。下面進入到邊相關的語法內容

邊類型

和點一樣,邊也可以有對應的類型

# Gremlin  創建邊類型
g.edgeLabel()
# nGQL  創建邊類型
CREATE EDGE edgeTypeName(propNameList)

邊的 CRUD

說完邊類型應該進入到邊的常規操作部分了

插入指定邊類型的邊

可以看到和點的使用語法類似,只不過在 Cypher 和 nGQL 中分別使用
-[]- 和
– 來表示關系,而 Gremlin 則用
to() 關鍵詞來標識指向關系,在使用這 3 種圖查詢語言的圖數據庫中的邊均為有向邊,下圖左邊為有向邊,右邊為無向邊。

# Gremlin  插入指定邊類型的邊
g.addE(String edgeLabel).from(v1).to(v2).property()
# Cypher  插入指定邊類型的邊
CREATE (node1-name : label1-name)-
 [(relationship-name : relationship-label-name)]
 - (node2-name : label2-name)
# nGQL  插入指定邊類型的邊
INSERT EDGE  edge_name  (prop_name_list) VALUES  src_vid  -   dst_vid : \
(prop_value_list)

刪除邊

# Gremlin  刪除邊
g.E(eid).drop()
# Cypher  刪除邊
MATCH (node1-name : label1-name)-[r:relationship-label-name]- ()
DELETE r
# nGQL  刪除邊
DELETE EDGE  edge_type   src_vid  -   dst_vid

查看指定邊

# Gremlin  查看指定邊
g.E(eid)
# Cypher  查看指定邊
MATCH (n)-[r:label]- ()
WHERE condition
RETURN properties(r)
# nGQL  查看指定邊
FETCH PROP ON  edge_name   src_vid  -   dst_vid

其他操作

除了常規的點、邊 CRUD 外,我們可以簡單看看這 3 種圖查詢語言的組合查詢。

指定點查指定邊

# Gremlin  指定點查指定邊
g.V(vid).outE(edge)
# Cypher  指定點查指定邊
Match (n)- [r:label]- []
WHERE id(n) = vid
RETURN r
# nGQL  指定點查指定邊
GO FROM  vid  OVER  edge

沿指定點反向查詢指定邊

在反向查詢中,Gremlin 使用了 in 來表示反向關系,而 Cypher 則更直觀的將指向箭頭反向變成
– 來表示反向關系,nGQL 則用關鍵詞
REVERSELY 來標識反向關系。

# Gremlin  沿指定點反向查詢指定邊
g.V(vid).inE(edge)
# Cypher  沿指定點反向查詢指定邊
MATCH (n) -[r:label]-()
# nGQL  沿指定點反向查詢指定邊
GO FROM  vid  OVER  edge  REVERSELY

無向遍歷

如果在圖中,邊的方向不重要(正向、反向都可以),那 Gremlin 使用
both(),Cypher 使用
-[]-,nGQL 使用關鍵詞
BIDIRECT。

# Traverse edges with specified vertices Gremlin
g.V(vid).bothE(edge)
# Traverse edges with specified vertices Cypher
MATCH (n)-[r:label]-()
# Traverse edges with specified vertices nGQL
GO FROM  vid  OVER  edge  BIDIRECT

沿指定點查詢指定邊 N 跳

Gremlin 和 nGQL 分別用 times 和 step 來表示 N 跳關系,而 Cypher 用
relationship*1..N 來表示 N 跳關系。

# Gremlin  沿指定點查詢指定邊  N  跳
g.V(vid).repeat(out( edge)).times(N)
# Cypher  沿指定點查詢指定邊  N  跳
MATCH (n)-[r:label*N]- ()
WHERE condition
RETURN r
# nGQL  沿指定點查詢指定邊  N  跳
GO N STEPS FROM  vid  OVER  edge

返回指定兩點路徑

# Gremlin  返回指定兩點路徑
g.V(vid).repeat(out()).until(vid).path()
# Cypher  返回指定兩點路徑
MATCH p =(a)-[.*]- (b)
WHERE condition
RETURN p
# nGQL  返回指定兩點路徑
FIND ALL PATH FROM  vid  TO  vid  OVER *

圖查詢語言·實操篇

說了一通語法之后,是時候展示真正的技術了——來個具體一點的例子。

示例圖:The Graphs of Gods

實操示例使用了
Janus Graph 的示例圖
The Graphs of Gods。該圖結構如下圖所示,描述了羅馬萬神話中諸神關系。

插入數據

#  插入點
## nGQL
nebula  INSERT VERTEX character(name, age, type) VALUES hash(saturn):(saturn , 10000,  titan), hash(jupiter):( jupiter , 5000,  god 
## Gremlin
gremlin  saturn = g.addV(character).property(T.id, 1).property(name ,  saturn).property(age , 10000).property(type ,  titan).next();
== v[1]
gremlin  jupiter = g.addV(character).property(T.id, 2).property(name ,  jupiter).property(age , 5000).property(type ,  god).next();
== v[2]
gremlin  prometheus = g.addV(character).property(T.id, 31).property(name ,  prometheus).property(age , 1000).property(type ,  god).next();
== v[31]
gremlin  jesus = g.addV(character).property(T.id, 32).property(name ,  jesus).property(age , 5000).property(type ,  god).next();
== v[32]
## Cypher
cypher  CREATE (src:character {name: saturn , age: 10000, type: titan})
cypher  CREATE (dst:character {name: jupiter , age: 5000, type: god})
#  插入邊
## nGQL
nebula  INSERT EDGE father() VALUES hash( jupiter)- hash(saturn):();
## Gremlin
gremlin  g.addE(father).from(jupiter).to(saturn).property(T.id, 13);
== e[13][2-father- 1]
## Cypher
cypher  CREATE (src)-[rel:father]- (dst)

刪除數據

# nGQL
nebula  DELETE VERTEX hash( prometheus 
# Gremlin
gremlin  g.V(prometheus).drop();
# Cypher
cypher  MATCH (n:character {name: prometheus}) DETACH DELETE n

更新數據

# nGQL
nebula  UPDATE VERTEX hash(jesus) SET character.type =  titan 
# Gremlin
gremlin  g.V(jesus).property(age , 6000);
== v[32]
# Cypher
cypher  MATCH (n:character {name: jesus}) SET n.type =  titan

查看數據

# nGQL
nebula  FETCH PROP ON character hash( saturn 
===================================================
| character.name | character.age | character.type |
===================================================
| saturn | 10000 | titan |
---------------------------------------------------
# Gremlin
gremlin  g.V(saturn).valueMap();
== [name:[saturn],type:[titan],age:[10000]]
# Cypher
cypher  MATCH (n:character {name: saturn}) RETURN properties(n)
 ╒════════════════════════════════════════════╕
 │ properties(n)  │
 ╞════════════════════════════════════════════╡
 │{name : saturn , type : titan , age :10000}│
 └────────────────────────────────────────────┘

查詢 hercules 的父親

# nGQL
nebula  LOOKUP ON character WHERE character.name ==  hercules  | \
 -  GO FROM $-.VertexID OVER father YIELD $$.character.name;
=====================
| $$.character.name |
=====================
| jupiter |
---------------------
# Gremlin
gremlin  g.V().hasLabel( character).has(name , hercules).out(father).values( name 
== jupiter
# Cypher
cypher  MATCH (src:character{name: hercules})-[:father]- (dst:character) RETURN dst.name
 ╒══════════╕
 │ dst.name │
 ╞══════════╡
 │ jupiter  │
 └──────────┘

查詢 hercules 的祖父

# nGQL
nebula  LOOKUP ON character WHERE character.name ==  hercules  | \
 -  GO 2 STEPS FROM $-.VertexID OVER father YIELD $$.character.name;
=====================
| $$.character.name |
=====================
| saturn |
---------------------
# Gremlin
gremlin  g.V().hasLabel( character).has(name , hercules).out(father).out(father).values( name 
== saturn
# Cypher
cypher  MATCH (src:character{name: hercules})-[:father*2]- (dst:character) RETURN dst.name
 ╒══════════╕
 │ dst.name │
 ╞══════════╡
 │ saturn  │
 └──────────┘

查詢年齡大于 100 的人物

# nGQL
nebula  LOOKUP ON character WHERE character.age   100 YIELD character.name, character.age;
=========================================================
| VertexID | character.name | character.age |
=========================================================
| 6761447489613431910 | pluto | 4000 |
---------------------------------------------------------
| -5860788569139907963 | neptune | 4500 |
---------------------------------------------------------
| 4863977009196259577 | jupiter | 5000 |
---------------------------------------------------------
| -4316810810681305233 | saturn | 10000 |
---------------------------------------------------------
# Gremlin
gremlin  g.V().hasLabel( character).has(age ,gt(100)).values( name 
== saturn
== jupiter
== neptune
== pluto
# Cypher
cypher  MATCH (src:character) WHERE src.age   100 RETURN src.name
 ╒═══════════╕
 │ src.name  │
 ╞═══════════╡
 │  saturn  │
 ├───────────┤
 │  jupiter  │
 ├───────────┤
 │  neptune  │
 │───────────│
 │  pluto  │
 └───────────┘

從一起居住的人物中排除 pluto 本人

# nGQL
nebula  GO FROM hash(pluto) OVER lives YIELD lives._dst AS place | GO FROM $-.place OVER lives REVERSELY WHERE \
$$.character.name !=  pluto  YIELD $$.character.name AS cohabitants;
===============
| cohabitants |
===============
| cerberus |
---------------
# Gremlin
gremlin  g.V(pluto).out(lives).in(lives).where(is(neq(pluto))).values( name 
== cerberus
# Cypher
cypher  MATCH (src:character{name: pluto})-[:lives]- () -[:lives]-(dst:character) RETURN dst.name
 ╒══════════╕
 │ dst.name │
 ╞══════════╡
 │ cerberus │
 └──────────┘

Pluto 的兄弟們

# which brother lives in which place?
## nGQL
nebula  GO FROM hash(pluto) OVER brother YIELD brother._dst AS god | \
GO FROM $-.god OVER lives YIELD $^.character.name AS Brother, $$.location.name AS Habitations;
=========================
| Brother | Habitations |
=========================
| jupiter | sky |
-------------------------
| neptune | sea |
-------------------------
## Gremlin
gremlin  g.V(pluto).out(brother).as(god).out(lives).as(place).select(god , place).by( name 
== [god:jupiter, place:sky]
== [god:neptune, place:sea]
## Cypher
cypher  MATCH (src:Character{name: pluto})-[:brother]- (bro:Character)-[:lives]- (dst)
RETURN bro.name, dst.name
 ╒═════════════════════════╕
 │ bro.name  │ dst.name │
 ╞═════════════════════════╡
 │  jupiter  │  sky  │
 ├─────────────────────────┤
 │  neptune  │  sea  │
 └─────────────────────────┘

關于圖數據庫查詢語言 Gremlin vs Cypher vs nGQL 的操作入門是怎樣的問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注丸趣 TV 行業資訊頻道了解更多相關知識。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-18發表,共計10677字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 峡江县| 长阳| 南开区| 广德县| 明溪县| 乡城县| 平果县| 甘肃省| 高碑店市| 龙江县| 旬邑县| 宾川县| 高密市| 普洱| 太和县| 尼木县| 恭城| 仁化县| 卓尼县| 利辛县| 蚌埠市| 北流市| 桂东县| 乐业县| 微山县| 仙桃市| 孝感市| 盐城市| 齐齐哈尔市| 乾安县| 友谊县| 河北区| 临沧市| 郯城县| 依兰县| 富蕴县| 信阳市| 浪卡子县| 诸城市| 兴义市| 峡江县|