janusGraph 图中添加索引可以很大幅度地提高检索图的速度。建议在新建schema时就为属性建立索引,否则,如果图中有旧数据,再建立索引 的话就需要为该索引执行重新索引操作。菌子试着做了几次,都没有成功,索引状态一直是installed无法装变为可用状态。关于索引的生命周期可以看下面的图片。
在janusgraph中,如果没有添加索引的话,查询节点
g.V().has('id','001a5a67-8db2-495b-bc74-39b58175f4a1')
的时候,如果没有索引会提示以下警告:
00:20:56 WARN org.janusgraph.graphdb.transaction.StandardJanusGraphTx - Query requires iterating over all vertices [(id = 001a5a67-8db2-495b-bc74-39b58175f4a1)]. For better performance, use indexes
废话不多说,让我们来看看怎么使用gremlin语言添加索引,以janusgraph为例。
janusgraph有多种索引,下面介绍其中的CompositeIndex索引,该索引是建立在图上的,不需要外部索引如Elasticsearch。该索引需要全文匹配,即如果索引建在属性id上,那么只有搜索的id可以完全匹配图里的id时索引才能有效,不支持模糊匹配。
建立索引可以分为以下几步:
第一步:关闭图中正在执行的事务。
需要注意的是,建立索引需要和对应属性在一个事务中进行,否则就需要重新索引,如若不然索引会一直处在installed状态,无法改变
//打开图
graph = JanusGraphFactory.open('conf/gremlin-server/janusgraph-hbase-es.properties');
g=graph.traversal();
mgmt=graph.openManagement();
//查询图中有几个没关的事务
count = graph.getOpenTransactions();
//把所有事务回滚(否则index会出错)
for(i=0;i<count;i++) {graph.getOpenTransactions().getAt(0).rollback()}
第二步:增加索引前需要保证图中存在需要加索引的那个属性。如果没有可以新建这个属性。
graph = JanusGraphFactory.open('conf/gremlin-server/janusgraph-hbase-es.properties');
g=graph.traversal();
mgmt=graph.openManagement();
//新增一个属性
mgmt.makePropertyKey('id').dataType(String.class).cardinality(LIST).make();
第三部:为属性加索引
首先获取该属性,接下来使用buildIndex的buildCompositeIndex添加索引。byIdComposite是索引名,可以随意起,iditem是需要加索引的属性,最后提交事务。
iditem = mgmt.getPropertyKey('id');
mgmt.buildIndex('byIdComposite', Vertex.class).addKey(iditem).buildCompositeIndex();
mgmt.commit()
第四部:等索引变为GISTERED状态
等等,事情还没有完。你还需要等待索引状态变为enable,但是如果试图直接变为enable状态,会出问题,导致变为installed状态,变为installed状态后则不能再转化为enable状态了。这个官网上也没说,也不知道是什么原因,特别坑。需要先等待索引变为REGISTERED,再等待索引状态变为enable。这个过程时间很长,需要耐心等待。
graph = JanusGraphFactory.open('conf/gremlin-server/janusgraph-hbase-es.properties');
g=graph.traversal();
mgmt=graph.openManagement();
mgmt.awaitGraphIndexStatus(graph, 'byIdComposite').status(SchemaStatus.REGISTERED).call()
ManagementSystem.awaitGraphIndexStatus(graph, 'byIdComposite').call()
第四步:等索引变为ENABLED状态,会返回一个状态,为success就建立成功了
ManagementSystem.awaitGraphIndexStatus(graph, 'byIdComposite').status(SchemaStatus.ENABLED).call()
附1:可以用下面的方法查询索引状态
//查询索引状态
mgmt = graph.openManagement()
index = mgmt.getGraphIndex('byid')
index.getIndexStatus(mgmt.getPropertyKey('id'))
附2:可以用下面的方法查看所有索引
mgmt.getGraphIndexes(Vertex.class)
附3:下面是重新索引的方法,有兴趣的小伙伴可以试试,如果成功了,请联系我,大家互相学习,谢谢
mgmt=graph.openManagement();
mgmt.updateIndex(mgmt.getGraphIndex('byIdComposite2'), SchemaAction.REINDEX).get();
mgmt.commit();