遍历框架示例
以下是遍历框架的一些使用示例。示例的源代码可在 TraversalExample.java
中找到。
此图展示了一个小群体朋友及其 RelationshipType
的定义
private enum Rels implements RelationshipType
{
LIKES, KNOWS
}
遍历图示例
例如,可以使用以下遍历器从 name = 'Joe'
的节点开始遍历图
for ( Path position : db.traversalDescription()
.depthFirst()
.relationships( Rels.KNOWS )
.relationships( Rels.LIKES, Direction.INCOMING )
.evaluator( Evaluators.toDepth( 5 ) )
.traverse( node ) )
{
output += position + "\n";
}
因此遍历将输出
(0)
(0)<-[LIKES,1]-(5)
(0)<-[LIKES,1]-(5)-[KNOWS,6]->(1)
(0)<-[LIKES,1]-(5)-[KNOWS,6]->(1)<-[KNOWS,5]-(6)
(0)<-[LIKES,1]-(5)-[KNOWS,6]->(1)-[KNOWS,4]->(4)
(0)<-[LIKES,1]-(5)-[KNOWS,6]->(1)-[KNOWS,4]->(4)-[KNOWS,3]->(3)
(0)<-[LIKES,1]-(5)-[KNOWS,6]->(1)-[KNOWS,4]->(4)-[KNOWS,3]->(3)-[KNOWS,2]->(2)
由于 TraversalDescription
是不可变的,因此创建包含不同遍历共享的通用设置的模板描述非常有用。例如,从以下遍历器开始
friendsTraversal = db.traversalDescription()
.depthFirst()
.relationships( Rels.KNOWS )
.uniqueness( Uniqueness.RELATIONSHIP_GLOBAL );
它产生以下输出(从 name = 'Joe'
的节点开始)
(0)
(0)-[KNOWS,0]->(2)
(0)-[KNOWS,0]->(2)<-[KNOWS,2]-(3)
(0)-[KNOWS,0]->(2)<-[KNOWS,2]-(3)<-[KNOWS,3]-(4)
(0)-[KNOWS,0]->(2)<-[KNOWS,2]-(3)<-[KNOWS,3]-(4)<-[KNOWS,4]-(1)
(0)-[KNOWS,0]->(2)<-[KNOWS,2]-(3)<-[KNOWS,3]-(4)<-[KNOWS,4]-(1)<-[KNOWS,6]-(5)
(0)-[KNOWS,0]->(2)<-[KNOWS,2]-(3)<-[KNOWS,3]-(4)<-[KNOWS,4]-(1)<-[KNOWS,5]-(6)
然后,从中创建一个新的遍历器,将深度限制为三
for ( Path path : friendsTraversal
.evaluator( Evaluators.toDepth( 3 ) )
.traverse( node ) )
{
output += path + "\n";
}
这应该是输出
(0)
(0)-[KNOWS,0]->(2)
(0)-[KNOWS,0]->(2)<-[KNOWS,2]-(3)
(0)-[KNOWS,0]->(2)<-[KNOWS,2]-(3)<-[KNOWS,3]-(4)
如果您想从深度 2 遍历到 4
for ( Path path : friendsTraversal
.evaluator( Evaluators.fromDepth( 2 ) )
.evaluator( Evaluators.toDepth( 4 ) )
.traverse( node ) )
{
output += path + "\n";
}
这产生以下输出
(0)-[KNOWS,0]->(2)<-[KNOWS,2]-(3)
(0)-[KNOWS,0]->(2)<-[KNOWS,2]-(3)<-[KNOWS,3]-(4)
(0)-[KNOWS,0]->(2)<-[KNOWS,2]-(3)<-[KNOWS,3]-(4)<-[KNOWS,4]-(1)
有关其他有用的评估器,请参阅 使用评估器。
Traverser
还具有一个 nodes()
方法,它返回路径中所有节点的 Iterable
for ( Node currentNode : friendsTraversal
.traverse( node )
.nodes() )
{
output += currentNode.getProperty( "name" ) + "\n";
}
这产生以下输出
Joe
Sara
Peter
Dirk
Lars
Lisa
Ed
您也可以对关系执行此操作。这是一个示例
for ( Relationship relationship : friendsTraversal
.traverse( node )
.relationships() )
{
output += relationship.getType().name() + "\n";
}
KNOWS
KNOWS
KNOWS
KNOWS
KNOWS
KNOWS
实现用户自定义过程
此示例展示了如何使用遍历框架实现 用户自定义过程。事务和日志器通过过程框架提供
@Context
public Transaction tx;
@Context
public Log log;
@Procedure(value = "traverse.findPeople")
@Description("Finds all the known people to the given Person")
public Stream<PathResult> findFriends(@Name("person") Node person) {
final Traverser traverse = tx.traversalDescription()
.breadthFirst()
.relationships(RelationshipType.withName("KNOWS"), Direction.OUTGOING)
.evaluator(Evaluators.toDepth(5))
.evaluator(new PathLogger())
.traverse(person);
return stream(traverse.iterator()).map(PathResult::new);
}
private final class PathLogger implements Evaluator {
@Override
public Evaluation evaluate(Path path) {
log.info(path.toString());
return Evaluation.INCLUDE_AND_CONTINUE;
}
}
这使得遍历框架可以与 Cypher 并行使用
MATCH (p:Person { name: 'Joe' })
CALL traverse.findPeople(p) YIELD path RETURN [friend IN nodes(path) | friend.name] AS friends