Используя neo4j 1.9.4, я пытаюсь найти подключенные компоненты (все доступные узлы) из начального узла, где связь имеет определенный атрибут ('с тех пор как') и этот атрибут имеет определенное целочисленное значение, например 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)")
Очевидно, ОТНОШЕНИЯ и РАВНО кажется, это неправильно.Я перенял это из примера 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
РЕДАКТИРОВАТЬ 2:Попытка выполнить предложенный запрос cypher от ulkas выдает мне следующую ошибку:
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"
^
РЕДАКТИРОВАТЬ 3:Предложение 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")
При переходе с Последнее родство () Для Конечный узел() это, по крайней мере, не возвращает мне ошибку, несмотря на то, что мне интересно узнать о множестве результатов, которые оно возвращает, поскольку ни один из узлов не имеет именно этого атрибута since?!Так что, похоже, даже тогда оценщик обрезки не приступает к работе.Я ожидал, что он остановится на каждом конечном узле, если не имеет свойства since или если оно не соответствует заданной дате?Что я делаю не так, есть какие-нибудь идеи?