Pergunta

Usando o Neo4J 1.9.4, estou tentando encontrar os componentes conectados (todos os nós acessíveis) de um nó inicial em que o relacionamento tem um determinado atributo ('desde') E este atributo tem um valor inteiro definido, por exemplo, 20130101.

Minha abordagem inicial estava usando uma consulta do Cypher, mas tive a sensação de que essa consulta Loops to Infinity se houver um loop dentro do gráfico? Pelo menos se eu não restringir o comprimento do caminho, e restringir o comprimento não é o que eu quero fazer.

Enquanto isso, comecei a usar uma travessia. Usando neo4jphp, uma travessia se parece com isso:

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

O que eu acho que preciso é algo assim:

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

Obviamente, RELAÇÃO e É IGUAL A parece estar errado. Eu adotei isso do exemplo https://github.com/jadell/neo4jphp/wiki/TraverSals, onde está definido o seguinte pruneelevater válido e funcional:

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

Não estou absolutamente familiarizado com o Javasscript, então não consigo descobrir como fazer isso. Além disso, como posso garantir que a travessia não resulte em um erro se houver um relacionamento que não tenha a propriedade "desde"? Se eu conseguir o mesmo usando uma consulta do Cypher, eu também aceitaria isso.

EDITAR: A propósito, minha abordagem usando Cypher foi a seguinte:

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: Experimente a consulta do Cypher sugerida da Ulkas me dê o seguinte erro:

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: A sugestão do Lamecode parecia realmente promissora, mas ainda assim retorna um erro:

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

E eu usei o seguinte pruneevaluator:

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

Ao mudar de Lastrelação () para endNode () Pelo menos não me devolve um erro, apesar de estar me perguntando sobre os muitos resultados que ele retorna, pois nenhum dos nós tem exatamente isso desde o atributo?! Parece que, mesmo assim, o avaliador de poda não começa a funcionar. Eu esperava que ele parasse em cada EndNode se não tiver uma propriedade desde a propriedade ou se é não qual é a data fornecida? O que estou fazendo de errado, alguma idéia?

Foi útil?

Solução

Em relação ao Traverser que você está usando. A variável 'Posição' JavaScript Prune Avaluator é um objeto de caminho. Ver: http://components.neo4j.org/neo4j/1.9.4/apidocs/org/neo4j/graphdb/path.html

Esses métodos devem estar disponíveis para você.

Usar lastRelationship() (Porque todos os relacionamentos anteriores já passaram pelo avaliador da poda).

O objeto de relacionamento herda de Contêiner de propriedade E isso tem um hasProperty() método.

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

Não tenho certeza se você precisa usar o método igual ou não, pois é JavaScript.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top