Neo4j - 遍历以查找特定的连接组件

时间:2013-11-07 17:48:39

标签: neo4j traversal neo4jphp

使用neo4j 1.9.4,我试图从关系具有特定属性的起始节点(' &)中找到连接的组件(所有可到达的节点) #39;)并且该属性具有定义的整数值,例如 20130101

我最初的方法是使用密码查询,但我觉得如果图中有循环,这个查询会循环到无穷大?至少如果我不限制路径长度并且限制长度不是我想要做的。

所以同时我开始使用遍历。使用neo4jphp遍历如下:

$traversal->setOrder(Everyman\Neo4j\Traversal::OrderBreadthFirst)
    ->setPruneEvaluator(Everyman\Neo4j\Traversal::PruneNone)
    ->setReturnFilter(Everyman\Neo4j\Traversal::ReturnAll)
    ->setUniqueness(Everyman\Neo4j\Traversal::UniquenessNodeGlobal);

我认为我需要的是这样的:

->setPruneEvaluator('javascript', "position.RELATIONSHIP().getProperty('since').EQUALS(20130101)")

显然, RELATIONSHIP EQUALS 似乎是错误的。 我从示例https://github.com/jadell/neo4jphp/wiki/Traversals中采用了这个,其中设置了以下有效且有效的pruneElevater:

->setPruneEvaluator('javascript', "position.endNode().getProperty('name').toLowerCase().contains('t')")

我完全不熟悉JavasScript,所以我无法弄清楚如何做到这一点。此外,如果存在没有属性的关系,我怎样才能确保遍历不会导致错误" ,因为"? 如果我可以使用密码查询来实现相同的目标,我也会接受它。

编辑:顺便说一句,我使用cypher的方法就是这样:

START n=node({start_node}) MATCH p = n-[*]-m WHERE ALL(x IN RELATIONSHIPS(p) WHERE HAS(x.since) AND x.since = 20130101) RETURN DISTINCT m

EDIT2 :尝试使用ulkas提供的cypher查询时出现以下错误:

Invalid query
string matching regex ``(``|[^`])*`' expected but `*' found
Think we should have better error message here? Help us by sending this query to cypher@neo4j.org.
Thank you, the Neo4j Team.
"START n=node(40317) MATCH p = n-[r:*..]-m WHERE has(r.since) AND r.since = 20130101 RETURN DISTINCT m"
                                    ^

EDIT3 :LameCode的建议看起来很有希望,但仍然会返回错误:

Fatal error: Uncaught exception 'Everyman\Neo4j\Exception' with message 'Unable to execute traversal [400]: Headers: Array ( [Content-Length] => 5183 [Content-Type] => application/json; charset=UTF-8 [Access-Control-Allow-Origin] => * [Server] => Jetty(6.1.25) ) Body: Array ( [message] => Failed to execute script, see nested exception. [exception] => EvaluationException [fullname] => org.neo4j.server.rest.domain.EvaluationException [stacktrace] => Array ( [0] => org.neo4j.server.scripting.javascript.JavascriptExecutor.execute(JavascriptExecutor.java:118) [1] => org.neo4j.server.rest.domain.EvaluatorFactory$ScriptedEvaluator.evalPosition(EvaluatorFactory.java:140) [2] => org.neo4j.server.rest.domain.EvaluatorFactory$ScriptedPruneEvaluator.evaluate(EvaluatorFactory.java:161) [3] => org.neo4j.graphdb.traversal.Evaluator$AsPathEvaluator.evaluate(Evaluator.java:69) [4] => org.neo4j.kernel.impl.traversal.TraverserIterator.eva in /var/www/vendor/everyman/neo4jphp/lib/Everyman/Neo4j/Command.php on line 116

我使用了以下pruneEvaluator:

->setPruneEvaluator('javascript', "position.lastRelationship().hasProperty('since') && position.lastRelationship().getProperty('since') == 20130101")

当从 lastRelationship()更改为 endNode()时,它至少不会给我一个错误,尽管我想知道它返回的很多结果,因为没有任何节点具有这个属性?!所以即便如此,修剪评估员也无法开展工作。我期望它在每个endNode停止,如果没有属性或者它是否在给定日期不相等?我做错了什么,有什么想法吗?

1 个答案:

答案 0 :(得分:0)

关于您正在使用的Traverser。 javascript prune计算器'position'变量是Path对象。请参阅:http://components.neo4j.org/neo4j/1.9.4/apidocs/org/neo4j/graphdb/Path.html

您应该可以使用这些方法。

使用lastRelationship()(因为所有以前的关系都已通过修剪评估者)。

Relationship对象继承自Property Container,并且具有hasProperty()方法。

setPruneEvaluator('javascript', "position.lastRelationship().hasProperty('since') && position.lastRelationship().getProperty('since') == 20130101")

我不确定你是否需要使用Equals方法,因为它是javascript。