簡體   English   中英

Titan cassandra不將定義的索引用於自定義gremlin步驟

[英]Titan cassandra does not use defined indexes for custom gremlin steps

我們在以下代碼塊中使用titan cassandra定義了5個索引

 def mgmt = g.managementSystem;
 try {
     if (!mgmt.containsGraphIndex("byId")) {
         def key = mgmt.makePropertyKey('__id').dataType(String.class).make()
         mgmt.buildIndex("byId",Vertex.class).addKey(key).buildCompositeIndex()
     }
     if (!mgmt.containsGraphIndex("byType")) {
          def key = mgmt.makePropertyKey('__type').dataType(String.class).make()
         mgmt.buildIndex("byType",Vertex.class).addKey(key).buildCompositeIndex()
     }
     if (!mgmt.containsGraphIndex("lastName")) {
         def key = mgmt.makePropertyKey('lastName').dataType(String.class).make()
         mgmt.buildIndex('lastName',Vertex.class).addKey(key).buildMixedIndex(INDEX_NAME)
     }
     if (!mgmt.containsGraphIndex("firstName")) {
         def key = mgmt.makePropertyKey('firstName').dataType(String.class).make()
         mgmt.buildIndex('firstName',Vertex.class).addKey(key).buildMixedIndex(INDEX_NAME)
     }
     if (!mgmt.containsGraphIndex("vin")) {
         def key = mgmt.makePropertyKey('vin').dataType(String.class).make()
         mgmt.buildIndex('vin',Vertex.class).addKey(key).buildMixedIndex(INDEX_NAME)
     }
     mgmt.commit()
 } catch (Exception e) {
     System.err.println("An error occurred initializing indices")
     e.printStackTrace()
 }

然后我們執行以下查詢

g.V.has('__id','49fb8bae5f994cf5825b849a5dd9b49a')

這會產生警告,通知我們:

“查詢需要遍歷所有頂點[{}]。為獲得更好的性能,請使用索引”

我很困惑,因為根據文檔,這些索引設置正確,但是由於某些原因,泰坦沒有使用它們。

索引是在圖形中的任何數據之前創建的,因此不需要重新索引。 任何幫助是極大的贊賞。

更新-我設法將其分解為一個非常簡單的測試。 在我們的代碼中,我們開發了一個定制的gremlin步驟,用於所述查詢

Gremlin.defineStep('hasId', [Vertex,Pipe], { String id ->
    _().has('__id', id)
})

然后從我們的代碼中調用

g.V.hasId(id)

看來,當我們使用自定義gremlin步驟時,查詢不使用索引,但是當使用香草gremlin調用時,則使用索引。

這篇文章中似乎注意到了類似的怪異之處https://groups.google.com/forum/#!topic/aureliusgraphs/6DqMG13_4EQ

我希望檢查屬性鍵的存在,這意味着您將檢查調整為:

if (!mgmt.containsRelationType("__id")) {

我在Titan Gremlin控制台中試用了您的代碼,但沒有看到問題:

gremlin> g  = TitanFactory.open("conf/titan-cassandra.properties")
==>titangraph[cassandrathrift:[127.0.0.1]]
gremlin> mgmt = g.managementSystem
==>com.thinkaurelius.titan.graphdb.database.management.ManagementSystem@2227a6c1
gremlin> key = mgmt.makePropertyKey('__id').dataType(String.class).make()
==>__id
gremlin> mgmt.buildIndex("byId",Vertex.class).addKey(key).buildCompositeIndex()
==>com.thinkaurelius.titan.graphdb.database.management.TitanGraphIndexWrapper@6d4c273c
gremlin> mgmt.commit()
==>null
gremlin> mgmt = g.managementSystem
==>com.thinkaurelius.titan.graphdb.database.management.ManagementSystem@79d743e6
gremlin> mgmt.containsGraphIndex("byId")
==>true
gremlin> mgmt.rollback()
==>null
gremlin> v = g.addVertex()
==>v[256]
gremlin> v.setProperty("__id","123")
==>null
gremlin> g.commit()
==>null
gremlin> g.V
12:56:45 WARN  com.thinkaurelius.titan.graphdb.transaction.StandardTitanTx  - Query requires iterating over all vertices [()]. For better performance, use indexes
==>v[256]
gremlin> g.V("__id","123")
==>v[256]
gremlin> g.V.has("__id","123")
==>v[256]

注意我沒有收到有關“ ...使用索引”的任何丑陋消息。 也許您可以在這里嘗試我的示例,然后在返回代碼之前查看其行為是否符合預期。

更新:回答上述有關自定義步驟的更新問題。 正如您發現的帖子所述,Titan的查詢優化器似乎無法解決這一問題。 我認為在此示例中很容易理解為什么:

gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> Gremlin.defineStep('hasName', [Vertex,Pipe], { n -> _().has('name',n) })
==>null
gremlin> g.V.hasName('marko')
==>v[1]
gremlin> g.V.hasName('marko').toString()
==>[GremlinStartPipe, GraphQueryPipe(vertex), [GremlinStartPipe, PropertyFilterPipe(name,EQUAL,marko)]]

“已編譯”的Gremlin看起來像上面的最后一行。 請注意,自定義步驟使用新的GremlinStartPipe編譯為“內部”管道。 將其與沒有自定義步驟的情況進行比較:

gremlin> g.V.has('name','marko').toString()
==>[GremlinStartPipe, GraphQueryPipe(has,vertex), IdentityPipe]

Titan可以使用嵌入的has優化“ GraphQueryPipe”,但是自定義步驟的簽名似乎並非如此。 我認為解決方法(至少對於此特定方案是編寫一個返回管道的函數。

gremlin> def hasName(g,n){g.V.has('name',n)}  
==>true
gremlin> hasName(g,'marko')
==>v[1]
gremlin> hasName(g,'marko').toString()
==>[GremlinStartPipe, GraphQueryPipe(has,vertex), IdentityPipe]

傳遞“ g”有點臭。 也許編寫您的DSL,以便將“ g”包裝在一個類中,然后您可以執行以下操作:

with(g).hasName('marko')

最后的想法是使用Groovy元編程工具:

gremlin> Graph.metaClass.hasName = { n -> delegate.V.has('name',n) }
==>groovysh_evaluate$_run_closure1@600b9d27
gremlin> g.hasName("marko").toString()                              
==>[GremlinStartPipe, GraphQueryPipe(has,vertex), IdentityPipe]
gremlin> g.hasName("marko")                                         
==>v[1]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM