遍历框架示例
以下是一些关于如何使用遍历框架的示例。这些示例的源代码可以在 TraversalExample.java
中找到。
此图说明了一小组朋友以及 RelationshipType
的定义
private enum Rels implements RelationshipType
{
LIKES, KNOWS
}
遍历图示例
例如,可以使用以下遍历器从名称为 '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 );
它会产生以下输出(从名称为 '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