Asset圖數據庫基於關係的查詢 - 關係遍歷
前面我們提到,相比關係型數據庫,Asset圖數據庫最大不同的特性就是關係是和實體一樣的一等公民。因此,GEL不僅支持基於屬性的查詢,而且支持基於關係的查詢。在構建基於關係的查詢之前,我們先來理解一下資產主數據中的關係。
以火車機車收集器中的兩個對象爲例,如下所示。
[
{
"uri": "/locomotives/1",
"type": "Diesel-electric",
"model": "ES44AC",
"serial_no": "001",
"emission_tier": "0+",
"fleet": "/fleets/up-1",
"manufacturer": "/manufacturers/GE",
"engine": "/engines/v12-1",
"installedOn": "01/12/2005",
"dateIso": "2005-12-01T13:15:31Z",
"hqLatLng": {
"lat": 33.914605,
"lng": -117.253374
}
},
{
"uri": "/locomotives/2",
"type": "Diesel-electric",
"model": "SD70ACe",
"serial_no": "002",
"emission_tier": "0+",
"fleet": "/fleets/up-1",
"manufacturer": "/manufacturers/electro-motive-diesel",
"engine": "/engines/v16-2-1",
"hqLatLng": {
"lat": 47.655492,
"lng": -117.427025
}
}
]
我們可以看到火車機車對象/locomotives/1
屬於車隊/fleets/up-1
,擁有引擎/engines/v12-1
,製造商爲/manufacturers/GE
,機車對象/locomotives/2
也有相類似的關係。根據這些信息,我們可以畫出如下對象關係網絡。
Asset數據庫中的所有關係都是有方向的,跟隨箭頭的方向查詢對象稱之爲向前遍歷,跟箭頭方向相反的查詢對象稱之爲向後遍歷。例如,在上圖中,從火車機車locomotives到製造商manufactures是向前遍歷。在上述JSON的描述中,製造商是火車機車對象的一個屬性,所以,“製造商爲”關係的方向是從火車機車到製造商。相同的道理,從車隊fleets到火車機車locomotives就是向後遍歷。多個對象可以指向同一個對象,這和我們在現實世界的直觀認知是一致的。例如,機車1和機車2都屬於同一個車隊up-1。隨着越來越多的對象和關係被添加進來,上述圖形就會隨之增長。
向前遍歷運算符>
當我們理解了Asset數據庫中對象間的關係,我們就可以開始構建基於關係的查詢了。例如,類型爲diesel-electric
的火車機車的製造商是哪家?向前遍歷運算符>
代表對象間向前遍歷查詢,因此,上述問題的查詢語句爲/manufacturers?filter=type=Diesel-electric>manufacturer
。我們來詳細解析一下這條GEL查詢語句的內部邏輯,這樣會幫助我們理解基於關係的查詢。
步驟 | 邏輯 | 語法 | 返回對象 |
---|---|---|---|
第一步 | 查詢所有類型爲Diesel-electric 的對象 |
filter=type=Diesel-electric |
在圖數據庫中,所有的對象都是同等重要的,沒有特定查詢起點。因此,過濾子句是面向Asset數據庫中的所有對象進行查詢,返回所有匹配的對象,包括火車機車對象和其他對象 |
第二步 | 在上一步返回的對象中,向前遍歷查詢關係是製造商爲manufacturer 所指向的對象 |
>manufacturer |
返回所有匹配的對象,包括製造商對象和其他由關係manufacturer 所指向的對象 |
第三步 | 在上一步返回的對象中,查詢收集器爲manufacturers 的對象 |
/manufacturers |
因爲有了收集器的限定,所以,返回所有匹配的對象,一定是製造商的對象信息 |
注:上述查詢語句中的
manufacturer
表示對象間的關係“製造商爲”,而manufacturers
表示收集器名稱是“製造商”。
那麼,向前遍歷的查詢和前面講到的通過篩選子句查找製造商信息有什麼區別麼?例如,/locomotives?filter=type=Diesel-electric&fields=manufacturer
也可以完成“類型爲diesel-electric
的火車機車的製造商是哪家?”這種查詢。但是,我們可以看到明顯的區別,
- 通過使用向前遍歷運算符,我們查詢到的是製造商對象的具體信息,包括,製造商的名稱,資質,等所有屬性。
- 通過使用篩選子句,我們查詢到的是火車機車對象中製造商的URI信息,而不是製造商對象的具體屬性信息。
向後遍歷運算符<
當我們理解了向前遍歷運算符,那麼理解向後遍歷運算符就比較容易了。例如,服務於客戶Union Pacific
的車隊有哪些?在第四節的數據建模中,我們定義了車隊服務於客戶的關係。因此,我們要完成上述查詢,就需要用到向後遍歷運算符<
,從車隊到客戶的關係中,通過客戶反向查詢車隊的信息。那麼,這個問題的查詢語句爲/fleets?filter=name=Union Pacific<customer
。我們還是詳細解析一下這條向後遍歷的GEL查詢語句。
步驟 | 邏輯 | 語法 | 返回對象 |
---|---|---|---|
第一步 | 查詢所有名稱爲Union Pacific 的對象 |
filter=name=Union Pacific |
返回所有匹配的對象,包括客戶對象和其他對象 |
第二步 | 在上一步返回的對象中,向後遍歷查詢含有關係是服務於customer 的對象 |
<customer |
返回所有匹配的對象,包括車隊對象和其他含有關係是customer 的對象 |
第三步 | 在上一步返回的對象中,查詢收集器爲fleets 的對象 |
/fleets |
因爲有了收集器的限定,所以,返回所有匹配的對象,一定是車隊的對象信息 |
當然,向前遍歷和向後遍歷運算符也可以一起使用。例如,生產引擎馬力爲4300的製造商還生產了哪些火車機車?GEL的查詢語句爲/locomotives?filter=horsepower=4300>manufacturer<manufacturer
。我們還可以設計其他更爲複雜的遍歷查詢,來滿足具體的業務需要。
作者:謝品,上海創新坊首席架構師,GE數字集團
專注於工業互聯網,雲計算,大數據,高性能分佈式存儲領域,對Cloud Foundry和傳統應用向雲端遷移,特別是向Predix遷移有豐富的經驗,曾供職於VMware,EMC,Autodesk等知名軟件公司雲計算部門。