[英]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.