我正在使用Neo4J Traversal API并试图从“1”遍历以找到符合下面模式的节点“2”和“3”:
1-[:A]-2-[:B]-3
然而,在我的遍历中,我被抓住了,因为还存在以下关系:
1-[:B]-3
据我了解,我的TraversalDescription
需要指定两种关系类型,但我不确定最优雅的方式来遍历:首先是关系,然后分支到:B关系。不幸的是,Direction
关系不能用来区分我的情况。
我的Scala代码是:
db.traversalDescription()
.evaluator(isAThenBRelationship)
.breadthFirst()
.relationships(A)
.relationships(B)
private val isAThenBRelationship = new PathEvaluator.Adapter() {
override def evaluate(path: Path, state: BranchState[Nothing]): Evaluation = {
if (path.length == 0) {
EXCLUDE_AND_CONTINUE
} else if (path.length == 1) {
Evaluation.of(false, path.relationships().iterator().next().getType.name() == A.toString)
} else {
Evaluation.of(path.relationships().iterator().next().getType.name() == B.toString, false)
}
}
}
顺便说一下,比较关系比这更好的方法是什么?
path.relationships().iterator().next().getType.name() == MyRelationship.toString
答案 0 :(得分:2)
多次使用relationships()
并不意味着订单。相反,有一个内部列表,relationships()
添加了一些内容。
要将特定关系类型限制为特定深度,您需要实现并使用自己的PathExpander
。下面的示例使用Java并使用匿名内部类实现PathExpander
:
traversalDescription.expand(new PathExpander<Object>() {
@Override
public Iterable<Relationship> expand(Path path, BranchState<Object> state) {
switch (path.length()) {
case 0:
return path.endNode().getRelationships(
DynamicRelationshipType.withName("A") );
case 1:
return path.endNode().getRelationships(
DynamicRelationshipType.withName("B") );
default:
return Iterables.empty();
}
}
@Override
public PathExpander<Object> reverse() {
// not used for unidirectional traversals
throw new UnsupportedOperationException();
}
});
Neo4j包含一个非常方便的类IteratorUtils
。因此,您的代码段可以写为(假设MyRelationship是RelationshipType
的实例:
IteratorUtil.first(path.relationships()).getType().equals(MyRelationship)
答案 1 :(得分:1)
除了@ StefanArmbruster的回答,这里是等效的Scala代码:
db.traversalDescription()
.breadthFirst()
.expand(isAThenBRelationship)
private val isAThenBRelationship =
new PathExpander[Object]() {
override def expand(path: Path, state: BranchState[Object]) =
path.length() match {
case 0 => path.endNode().getRelationships(DynamicRelationshipType.withName("A"))
case 1 => path.endNode().getRelationships(DynamicRelationshipType.withName("B"))
case _ => Iterables.empty()
}
override def reverse(): PathExpander[Object] = ???
}
请注意,扩展器必须在关系之后。