我们在下面的代码块中使用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步骤时,查询不会使用索引,但在使用vanilla gremlin调用时,会使用索引。
在这篇文章中看起来有点奇怪 https://groups.google.com/forum/#!topic/aureliusgraphs/6DqMG13_4EQ
答案 0 :(得分:1)
我希望检查是否存在属性键,这意味着您将支票调整为:
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]