Neo4j - обход для поиска конкретного подключенного компонента

StackOverflow https://stackoverflow.com/questions/19843027

  •  29-07-2022
  •  | 
  •  

Вопрос

Используя 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 или если оно не соответствует заданной дате?Что я делаю не так, есть какие-нибудь идеи?

Это было полезно?

Решение

Что касается Траверсера, который вы используете.Переменная 'position' javascript prune evaluator - это объект Path.Видишь: http://components.neo4j.org/neo4j/1.9.4/apidocs/org/neo4j/graphdb/Path.html

Эти методы должны быть доступны вам.

Использование lastRelationship() (потому что все прежние отношения уже прошли через оценщик prune).

Объект отношения наследуется от Контейнер свойств и это имеет hasProperty() способ.

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

Я не уверен, нужно ли вам использовать метод Equals или нет, поскольку это javascript.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top