2
votes

I have a following Cypher query that returns all Decision that belong to a particular Tag:

MATCH (d:Decision)-[:BELONGS_TO]->(t:Tag) WHERE t.id = {tagId} RETURN d

According to my business logic every Tag can have a set of synonyms:

(t:Tag)<-[:FOR]-(ts:TagSynonym)-[:HAS]->(s:Tag) 

and every s:Tag can also have a synonyms associated at the same way.. unlimited depth and where ts.approved = true.

Could you please show how to extend the first query in order to return not only Decisions associated with a start tag (t.id = {tagId}) but also the all Decisions associated with all tag's synonyms(unlimited depth).

Ideally all of these Decisions should be returned under one d variable.

Right now I'm playing with the following query:

MATCH p=(t:Tag)-[:FOR|HAS*]-(end:Tag) 
WHERE t.id = {tagId} AND NOT (end)<-[:FOR]-() 
OPTIONAL MATCH (d:Decision)-[:BELONGS_TO]->(tag) 
RETURN d

but it doesn't work.

UPDATED

I have created a Neo4j sandbox:

http://54.165.53.29:33761/browser/
neo4j
timer-rocks-hilltop

Please use the following query:

MATCH p=(t:Tag)-[:FOR|HAS*0..]-(end:Tag) 
WHERE t.id = 1 AND NOT (end)<-[:FOR]-() 
MATCH (d:Decision)-[:BELONGS_TO]->(end) 
RETURN d

It returns only the last Decision in the path(Decision3) but should also return Decision1 and Decision 2.

This is the sample database username/password: neo4j/neo4j1

I have a 3 Tag and 3 Decision associated with this tag.

Also

Tag 2 is a synonym of Tag 1 and Tag 3 is a synonym of Tag 2.

I need to find all of the Decision by Tag 1 and by its synonyms(Tag 2 and Tag 3). This is decisions: Decision1, Decision2, Decision 3

1
Can you plese post some sample of your data set and the expected result?Bruno Peres
Sure, I have updated my questionalexanoid

1 Answers

3
votes

There is a subtle thing with variable depth traversals which is the zero depth :

MATCH p=(t:Tag)-[:FOR|HAS*0..]-(end:Tag) 
WHERE t.id = {tagId} AND NOT (end)<-[:FOR]-() 
MATCH (d:Decision)-[:BELONGS_TO]->(end) 
RETURN d

The idea is that, it handles both the cases where t nodes have a FOR or HAS relationships and when they not. The trick is that found tags (even the t node hence the 0) are under the end alias.

You can find a more in depth documentation about variable length relationships in this article : https://graphaware.com/graphaware/2015/05/19/neo4j-cypher-variable-length-relationships-by-example.html

EDIT

It seems the logic for finding the Tag nodes is wrong on your side, the query returns only one Tag due to this part in the query AND NOT (end)<-[:FOR]-(). Remove it and you'll see it returns 3 Decisions