Neo4j 写入TraversalDescription以排除具有某些属性的边
我想写一个描述,我可以用步行者。我的最终目标是将Walker传递给GraphvizWriter,以便以.dot格式获得遍历结果 在我的图中,我只有一种类型的节点和一种类型的关系。每个关系都有一个名为“inCommon”的属性,该属性具有数值。我只需要在节点之间的关系上具有inCommon>=15的节点 下面是我的traversalDescription的样子:Neo4j 写入TraversalDescription以排除具有某些属性的边,neo4j,Neo4j,我想写一个描述,我可以用步行者。我的最终目标是将Walker传递给GraphvizWriter,以便以.dot格式获得遍历结果 在我的图中,我只有一种类型的节点和一种类型的关系。每个关系都有一个名为“inCommon”的属性,该属性具有数值。我只需要在节点之间的关系上具有inCommon>=15的节点 下面是我的traversalDescription的样子: traversalDescription = graphDb.traversalDescription(); traversalDesc
traversalDescription = graphDb.traversalDescription();
traversalDescription = traversalDescription.breadthFirst();
traversalDescription = traversalDescription.evaluator(pathEvaluator);
traversalDescription = traversalDescription.relationships(type, Direction.BOTH);
pathEvaluator是我编写的一个类的实例,它试图只返回我想要的边
public class ReferentEvaluator implements PathEvaluator {
@Override
public Evaluation evaluate(final Path path) {
if(path!=null){
Iterator iter=path.relationships().iterator();
while(iter.hasNext()){
Relationship r=(Relationship)iter.next();
if(r!=null){
Integer inCommon=(Integer)r.getProperty(r.getPropertyKeys().iterator().next());
if(inCommon.intValue() < 15){
return Evaluation.EXCLUDE_AND_CONTINUE;
}
}
else{
return Evaluation.EXCLUDE_AND_CONTINUE;
}
}
return Evaluation.INCLUDE_AND_CONTINUE;
}
return Evaluation.EXCLUDE_AND_CONTINUE;
}
}
公共类引用评估器实现路径评估器{
@凌驾
公共评估(最终路径){
if(路径!=null){
迭代器iter=path.relationships().Iterator();
while(iter.hasNext()){
关系r=(关系)iter.next();
如果(r!=null){
整数inCommon=(整数)r.getProperty(r.getPropertyKeys().iterator().next());
if(inCommon.intValue()<15){
返回Evaluation.EXCLUDE_并_CONTINUE;
}
}
否则{
返回Evaluation.EXCLUDE_并_CONTINUE;
}
}
返回评估。包括_和_CONTINUE;
}
返回Evaluation.EXCLUDE_并_CONTINUE;
}
}
我看到的是,这不起作用。不常见<15的关系也包括在内。实际上,这种方法似乎根本不起作用。我是不是走错了路?或者我在这里做的事情越来越近了?我认为在
路径扩展程序中实现关系过滤器比在计算器中实现关系过滤器更好。这样做的原因是,您可以提前决定跳过哪些路径,而不需要加载节点并在以后过滤掉
您提供的不是relationships()
而是一个自定义PathExpander
。PathExpander
使用谓词过滤给定类型的所有关系。谓词检查inCommon
是否<15
由于我们在扩展器中完成了所有的脏活,因此我们可以节省使用一个计算器,该计算器使用INCLUDE\u和\u CONTINUE
-计算器进行回复。all()
可以完成这一操作
以下是我未经测试的代码片段:
import org.neo4j.helpers.Predicate;
import org.neo4j.helpers.collection.Iterables;
import ...
public void traversalSample() {
TraversalDescription td = graphDatabaseService
.traversalDescription()
.expand(new RelationshipPropertyFilterExpander(
DynamicRelationshipType.withName("KNOWS"), Direction.BOTH,
"inCommon", 15)
)
.evaluator(Evaluators.all());
td.traverse(.....);
}
class RelationshipPropertyFilterExpander implements PathExpander<Object> {
public RelationshipType type;
public Direction direction;
public String propName;
int threshold;
public RelationshipPropertyFilterExpander(RelationshipType type, Direction direction,
String propName, int threshold) {
this.type = type;
this.direction = direction;
this.propName = propName;
this.threshold = threshold;
}
@Override
public Iterable<Relationship> expand(Path path, BranchState<Object> state) {
Node endNode = path.endNode();
Predicate<? super Relationship> predicate = new Predicate<Relationship>() {
@Override
public boolean accept(Relationship relationship) {
// if relationship property is not set, we assume 0
return Integer.parseInt(relationship.getProperty(propName, "0").toString()) < threshold;
}
};
return Iterables.filter(predicate, endNode.getRelationships(type, direction));
}
@Override
public PathExpander<Object> reverse() {
// gets never called in a unidirectional traversal
throw new UnsupportedOperationException();
}
}
import org.neo4j.helpers.Predicate;
导入org.neo4j.helpers.collection.Iterables;
导入。。。
public void transversalsample(){
TraversalDescription td=graphDatabaseService
.traversalDescription()
.expand(新关系属性过滤Expander)(
DynamicRelationshipType.withName(“知道”),Direction.BOTH,
“不常见”,15)
)
.evaluator(Evaluators.all());
td.导线测量(…);
}
类RelationshipPropertyFilterExpander实现PathExpander{
公共关系类型;
公共方向;
公共字符串名称;
int阈值;
public RelationshipPropertyFilterExpander(RelationshipType类型、方向、,
字符串名称(整数阈值){
this.type=type;
这个方向=方向;
this.propName=propName;
这个阈值=阈值;
}
@凌驾
公共Iterable扩展(路径、分支状态){
Node endNode=path.endNode();
Predicate我认为在PathExpander
中实现关系过滤器比在Evaluator
中实现关系过滤器更好。原因是您可以提前决定跳过哪些路径,而不需要加载节点并在以后过滤掉
您提供的不是relationships()
而是一个自定义PathExpander
。PathExpander
使用谓词过滤给定类型的所有关系。谓词检查inCommon
是否<15
由于我们在扩展器中完成了所有的脏活,因此我们可以节省使用一个计算器,该计算器使用INCLUDE\u和\u CONTINUE
-计算器进行回复。all()
可以完成这一操作
以下是我未经测试的代码片段:
import org.neo4j.helpers.Predicate;
import org.neo4j.helpers.collection.Iterables;
import ...
public void traversalSample() {
TraversalDescription td = graphDatabaseService
.traversalDescription()
.expand(new RelationshipPropertyFilterExpander(
DynamicRelationshipType.withName("KNOWS"), Direction.BOTH,
"inCommon", 15)
)
.evaluator(Evaluators.all());
td.traverse(.....);
}
class RelationshipPropertyFilterExpander implements PathExpander<Object> {
public RelationshipType type;
public Direction direction;
public String propName;
int threshold;
public RelationshipPropertyFilterExpander(RelationshipType type, Direction direction,
String propName, int threshold) {
this.type = type;
this.direction = direction;
this.propName = propName;
this.threshold = threshold;
}
@Override
public Iterable<Relationship> expand(Path path, BranchState<Object> state) {
Node endNode = path.endNode();
Predicate<? super Relationship> predicate = new Predicate<Relationship>() {
@Override
public boolean accept(Relationship relationship) {
// if relationship property is not set, we assume 0
return Integer.parseInt(relationship.getProperty(propName, "0").toString()) < threshold;
}
};
return Iterables.filter(predicate, endNode.getRelationships(type, direction));
}
@Override
public PathExpander<Object> reverse() {
// gets never called in a unidirectional traversal
throw new UnsupportedOperationException();
}
}
import org.neo4j.helpers.Predicate;
导入org.neo4j.helpers.collection.Iterables;
导入。。。
public void transversalsample(){
TraversalDescription td=graphDatabaseService
.traversalDescription()
.expand(新关系属性过滤Expander)(
DynamicRelationshipType.withName(“知道”),Direction.BOTH,
“不常见”,15)
)
.evaluator(Evaluators.all());
td.导线测量(…);
}
类RelationshipPropertyFilterExpander实现PathExpander{
公共关系类型;
公共方向;
公共字符串名称;
int阈值;
public RelationshipPropertyFilterExpander(RelationshipType类型、方向、,
字符串名称(整数阈值){
this.type=type;
这个方向=方向;
this.propName=propName;
这个阈值=阈值;
}
@凌驾
公共Iterable扩展(路径、分支状态){
Node endNode=path.endNode();
谓词关于遍历框架,需要了解的重要一点是它在路径上运行。求值器总是获取从起始节点到图中当前位置的整个路径。因此,需要了解的第二个重要事项是,路径之间的区别状态更改是它们的结束节点。求值器将l每次调用evaluate()
都会得到一个以新节点结尾的路径(有时取决于遍历的其他限制,请参见唯一性等)
这里重要的是,您的求值器总是遍历当前路径的所有边,并且在发现一条具有以下特性的边时立即进行迭代
Evaluator traversal:
(6)
(6)--[KNOWS,0]-->(1)
(6)--[KNOWS,0]-->(1)<--[KNOWS,2]--(4)
(6)<--[KNOWS,1]--(3)--[KNOWS,6]-->(0)
(6)--[KNOWS,0]-->(1)<--[KNOWS,2]--(4)<--[KNOWS,3]--(5)
(6)<--[KNOWS,1]--(3)--[KNOWS,6]-->(0)<--[KNOWS,7]--(7)
Nodes with 'inCommon' edges >= 15:
Joe
Sara
Peter
Lars
Dirk
Nici