Neo4j: Terms of Relationship with Depth

What am i trying to do

Being relatively new to Neo4j, I am trying to find specific nodes with Cypher in the Neo4j chart database . The nodes must be connected by a chain of a chain of a certain type with additional relationship conditions :

// Cypher START self = node(3413) MATCH (self)<-[rel:is_parent_of*1..100]-(ancestors) WHERE rel.some_property = 'foo' RETURN DISTINCT ancestors 

What's wrong.

If I omitted part of the depth *1..100 , the request will work, but, of course, then only one relationship between self and ancestors will be allowed.

But if I allow ancestors be a few steps away from self by entering a depth of *1..100 , the request fails:

Error: Expected rel as a map, but it was a collection

I thought maybe this syntax defines rel as is_parent_of*1..100 , and not the definition of rel as a relationship of type is_parent_of and allows you to increase the depth of the relationship.

So, I tried to make my intentions understandable with parentheses: [(rel:is_parent_of)*1..100 . But this causes a syntax error.

I would appreciate any help to fix this. Thanks!

+6
source share
1 answer

Nomenclature

The call to depth *1..100 comes from the nomenclature of a non-graphic ruby โ€‹โ€‹stone , where this is done using the abstract depth method.

In neo4j, this is called variable-length relationships , which can be seen here in the documentation: MATCH / variable-length relationships .

Cause of error

The reason for the error โ€œIt is expected that rel will be a map, but it was a collectionโ€, really, is that rel does not apply to each individual relationship, but to the totality of the related relations.

See the example here in the documentation: MATCH / Relationship variable in variable-length relationships .

Decision

First, confirm that the identifier refers to the collection (i.e. rels many elements), and name it rels instead of rel . Then, in WHERE specify that the condition should apply to all rel elements in the rels collection using the ALL predicate .

 // Cypher START self = node(3413) MATCH (self)<-[rels:is_parent_of*1..100]-(ancestors) WHERE ALL (rel in rels WHERE rel.some_property = 'foo') RETURN DISTINCT ancestors 

The ALL predicate is explained here in the documentation: Functions / Functions of the predicate .

The answer to this question led me to this decision.

Long time request

Unfortunately, querying relationship properties is time consuming. The above query, containing only a couple of nodes in the database, takes more than 3000 ms on my development machine.

+8
source

Source: https://habr.com/ru/post/957630/


All Articles