2013-04-21 89 views
3

我一直在研究Tinkerpop堆棧很長一段時間。我想我對它可以做什麼以及它可以很好地工作的數據庫有個很好的想法。我現在正在考慮一些不同的數據庫,但還沒有確定。所以我決定將我的代碼純粹寫入接口,並且現在不考慮的任何實現。在我看到的數據庫中,它們實現TransactionalGraphKeyIndexableGraph。我認爲這足夠滿足我需要的,但我只有一個問題。Tinkerpop Blueprints頂點查詢

我有不同的'類'的頂點。使用藍圖,我認爲最好通過在包含類名的每個頂點中包含一個字段來表示。這樣做,我可以做類似graph.getVertices("classname", "User")的東西,它會給我所有的用戶頂點。由於getVertices函數指定一個實現應該使用索引,我保證會得到一個快速查找(如果我索引該字段)。

但讓我們說,我想基於兩個屬性檢索頂點。頂點必須有className=Usersusername=admin。尋找單個頂點的最佳方法是什麼?是否有可能索引這兩個屬性,即使並非所有的頂點都有username字段?我想要的數據庫是OrientDB,Neo4j和Titan,但我還沒確定。我目前也計劃使用Gremlin,如果有幫助的話。

回答

3
  1. graph.getVertices()會遍歷所有頂點,尋找那些與財產,如果你沒有自動指數在圖形中實現開啓。如果你已經有了數據,並不能只是打開自動索引,你應該用的是index = indexableGraph.getIndex()然後index.get('classname', 'User')

  2. 很可能在多個對象進行query,但沒有細節,就很難說了。對於Neo4j他們使用Lucene,這意味着query()將採用lucene查詢,如className:Users AND username:admin,但我不能爲其他人說話。

呀這些DB的是良好的擺弄,我個人認爲neo4j是最容易,只要你瞭解他們的許可結構,你不應該使用它們有任何問題。

+0

那麼,正如你所說,查詢有些實現特定(不幸)。我希望能夠隨時切換數據庫,所以我只寫了我自己的查詢包裝器。謝謝你的幫助。 – GJK 2013-04-22 02:08:39

+0

是的,這很不幸,但這是大多數這些系統構建的方式,有些可能沒有執行特定類型的查詢的能力,因此他們將其留在了實現特定的位置。 – Nicholas 2013-04-22 02:12:09

+0

說'graph.getVertices()'做線性掃描是不正確的。如果圖形實現KeyIndexableGraph(以及所有提到的三個圖),並且指定的密鑰是作爲密鑰索引創建的密鑰,則使用索引並避免線性掃描。 https://github.com/tinkerpop/blueprints/wiki/Graph-Indices#keyindexablegraph-and-fast-lookup-of-elements-by-keyvalue-pairs – 2013-04-22 11:02:08

4

對頂點使用「類」或「類型」是劃分它們的好方法。這樣做的:

graph.createKeyIndex("classname",Vertex.class); 
graph.getVertices("classname", "User"); 

是一個很常見的模式,一般應該產生一個快速查找,但迭代數千萬用戶的一個索引可能不會那麼大(如果你打算種植特定classname到非常大的尺寸)。我認爲這導致了您的問題的第二部分,關於做兩個財產查詢。

以表面上的例子,這兩個元素的查找會是這樣的(使用小鬼):

g.V('classname',"User").has('username','admin') 

所以,你縮小頂點只是「用戶」的頂點與鍵索引,然後過濾那些爲「管理員」。但是,我會以不同的方式進行建模。這將是更便宜的只需做:

graph.createKeyIndex("username",Vertex.class); 
graph.getVertices("username", "admin"); 

或小鬼:

g.V('username','admin') 

如果你知道你想要的用戶名,還有來模擬這個沒有更好/更快的方法。如果你想遍歷所有的「用戶」頂點,你真的只需要classname。如果你只是想找到一個(或一組與username頂點),那麼對該屬性的關鍵索引是更好的方法。

即使我沒有在其上創建密鑰索引,我仍然在所有頂點上包含typeclassname屬性。我發現它有助於全球運營,我可能會或可能不關心速度,但只需要一個答案。

+0

問題在於,我無法保證User類將是唯一具有用戶名字段的頂點類。我們的數據模型是靈活的,可以由用戶間接編輯。不能保證不同類的頂點不會共享屬性名稱。 – GJK 2013-04-22 19:04:03

+1

完全沒有問題。該索引不需要唯一標識特定用戶(雖然它可以很好)。使用索引讓你關閉,然後過濾類。考慮以下區別:'gV('classname','user')。has('username','admin')''和'gV('username','admin')。has('classname','user' )'。第一個必須讓所有的用戶(可能有數千個或更多),然後循環他們來找到「管理員」。第二種情況要好得多,因爲即使圖表中存在多次「用戶名」,它可能也不會返回數千次,因此您只需掃描一小撮即可找到「用戶」類。 – 2013-04-23 13:50:01

+1

或者,確保架構中的唯一性。如果你不介意你的屬性名稱的冗長,沒有理由不能用類型名稱來加前綴。所以也許你覺得你需要在「用戶」類和「博客」類中存儲用戶名(表示是誰寫了一篇文章)。只需調用「用戶」類頂點屬性「用戶名」,並調用「博客」類屬性「blogUsername」。這樣你確保你的索引總是返回一個類的一件事。 – 2013-04-23 13:54:18