目录
二、Vertex Step (Vertex centric)
首先我们假定读者对Gremlin语句有一定的了解,那么Traversal就是对gremlin语句用java语法中的方法进行拼接。看一下JanusGraph官方文档中对traversal的使用:
JanusGraph graph = JanusGraphFactory.open('conf/janusgraph-cql.properties')
GraphTraversalSource g = graph.traversal()
saturn = g.V().has('name', 'saturn').next()
一、Terminal Step
traversal方法首先返回一个GraphTraversalSource类型,这个类型可以执行图相关的搜索,也就是根据条件从全图进行搜索,然后返回traversal,在后续若干个traversal后,最终结果在next方法后返回。这个方法被称为ternimal step,与他作用相同的一共有9个,他们的作用是终止traversal的添加过程,转而对前面设置的条件开始图查询。
g.V().out('created').hasNext()
g.V().out('created').next()
g.V().out('created').next(2)
g.V().out('nothing').tryNext()
g.V().out('created').toList()
g.V().out('created').toSet()
g.V().out('created').toBulkSet()
results = ['blah',3]
g.V().out('created').fill(results)
g.addV('person').iterate()
本节中,我们重点关注GraphTraversalSource类在全局搜索时的工作方式。
二、Vertex Step (Vertex centric)
(1) 从一个简单的api查询开始
// Traversal.toList
g.V().toList()
// Traversal.fill()
final Traverser<E> traverser = endStep.next();
TraversalHelper.addToCollection(collection, traverser.get(), traverser.bulk());
// AbstractStep.next();
final Traverser.Admin<E> traverser = this.processNextStart();
if (null != traverser.get() && 0 != traverser.bulk())
return this.prepareTraversalForNextStep(traverser);
- 前面我们介绍了final step,toLIst属于一个final setp,所以与前面的查询链返回traverser不同,这次调用的是fill方法。也就是将结果填入到给出的collection继承类中返回。
- 每一次endStep.next方法返回一个traverser,添加到结果集,所以接下来我们关注这个traverser是怎么生成的
(2)
// AbstractStep.processNextStart
this.head = this.starts.next();
this.iterator = this.flatMap(this.head);
return this.head.split(this.iterator.next(), this);
- 将 (ExpandableStepIterator<S> implements Iterator<Traverser.Admin<S>>)的next()方法返回值给(Traverser) head
- iterator 保存了flatMap返回的result
- 然后我们返回值是一个由原traverser clone出的新traverser,但是将result中的next添加了进去,clone iterator的同时,指针也向后移动了
- 此时可以看到两个关键节点,head和 iterator,分别记录了traverser 和 result iterator
(2.1)我们关注在 this.starts.next() 发生了什么,怎么返回的结果
// ExpandableStepIterator.next
if (this.hostStep.getPreviousStep().hasNext())
return this.hostStep.getPreviousStep().next();
return this.traverserSet.remove();
从字面意义上看,先查询了前一个step时候有结果,如果有的话,返回这个结果。但是hasNext方法却不只是简单的判断。
// AbstractStep.hasNext
public boolean hasNext() {
if (null != this.nextEnd)
return true;
else {
try {
while (true) {
if (Thread.interrupted()) throw new TraversalInterruptedException();
this.nextEnd = this.processNextStart();
if (null != this.nextEnd.get() && 0 != this.nextEnd.bulk())
return true;
else
this.nextEnd = null;
}
} catch (final NoSuchElementException e) {
return false;
}
}
}
- 总结一下就是将上一个step的processNextStart方法的返回值给他的nextEnd属性
public Traverser.Admin<E> next() {
if (null != this.nextEnd) {
try {
return this.prepareTraversalForNextStep(this.nextEnd);
} finally {
this.nextEnd = null;
}
}
}
- 然后返回这个traverser
(3)那么看到result是如何被一次次拿出来的,加下来关注result是如何生成的
// AbstractStep.flatMap(this.head)
Iterator<E> flatMap(final Traverser.Admin<Vertex> traverser)
//
JanusGraphVertexStep.flatMap ==> query.vertices()
(4) 中间一些复杂的封装
VertexCentricQueryBuilder.vertices ===> execute()
VertexCentricQueryBuilder.execute ===> return resultConstructor.getResult(vertex,bq);
VertexConstructor.getResult ===> return executeVertices(v,bq);
BasicVertexCentricQueryBuilder.executeVertices ===> return executeIndividualVertices(vertex,baseQuery);
SimpleVertexQueryProcessor.vertexIds ===> Iterables.transform(
CacheVertex.loadRelations ===> lookup.get(query)
SimpleVertexQueryProcessor.getBasicIterator ===> tx.getGraph().edgeQuery()
(4) JanusGraph
StandardJanusGraph.edgeQuery ===> tx.edgeStoreQuery()
(5) 存储层的操作
// Backend
BackendTransaction.edgeStoreQuery ===> call
KCVSProxy.getSlice ===> store.getSlice(query, unwrapTx(txh))
HBaseKeyColumnValueStore.getSlice ===> getHelper()
HBaseKeyColumnValueStore.getHelper ===> table.get(requests);
本文是JanusGraph入坑笔记的第五篇,重点探讨GraphTraversal的Terminal Step和Vertex Step(Vertex centric)。首先解释了Terminal Step如何终止traversal并启动图查询,接着详细阐述Vertex Step,特别是从API查询开始,解析traverser的生成、遍历过程以及结果的获取,深入到存储层的操作。
188

被折叠的 条评论
为什么被折叠?



