1

I am a beginner on cypher and want to create a query that find all nodes that connect to specific nodes that other node connect to them, see the example

I need to get all the brown nodes that connect to the red nodes that the blue node connect to it.

for this example I want to get the brown nodes Ids: 2, 3 and 1 (because no red nodes needs to get it)

For now I did it on 2 different queries and use python to find it, but now I need to do this in 1 query.

Match (r:R)-[]-(a:A) return collect(a.Id)

and the second query:

Match (b:B) Optional Match (b)-[]-(a:A) return b.Id, collect(a.Id)

and in my script check if every record from the second query is a subset of the first list of all a.Id that connect to R

can I do it in 1 query? Thank!

Kelvin Lawrence
  • 14,674
  • 2
  • 16
  • 38
  • I think you mean that you want to get the brown nodes 2,3,4 but not 1 since that is not connected via a red node. Is that correct? – bechbd Dec 06 '21 at 17:12
  • @bechbd Hi, no this is not what I mean, I will try to explain it in other words, I need to get all the brown nodes that if they connect to red nodes the blue node must connect to all of them, in this example, B-4 not connect to 3 reds but the blue connect to only 2 of them, so I don't want B-4. B-2 and B-3 connect to the same reds that the blue connect so it is OK, for B-1 , because it is not connect to any red it is OK, hope it make sense :) – Matan Avitan Dec 07 '21 at 08:33

1 Answers1

0

Improved answer: Start with :B nodes and check if all their :A neighbours are have a link to :R the ALL() function also returns true if :B does not have any neighbours

MATCH (b:B)
WHERE ALL(n IN [(b)--(a:A) | a] WHERE EXISTS ((n)--(:R))  ) 
RETURN b

enter image description here

Graphileon
  • 5,275
  • 3
  • 17
  • 31
  • Hi, thanks, I understand the logic but I think it will not match the b-1 node (because there is no path to get it between r and b. Although I tried the query and get the Error: `{ "detailedMessage": "Variable ' REL139' not defined (line 3, column 12 (offset: 108))", "requestId": "a9af83f2-bc32-4a72-ab16-3111cd6e81bb", "code": "MalformedQueryException" }` my query is: `Match (r:Respondent)--(a:Answer)--(rule:Rule) WITH r, rule, collect(distinct a) as answersNodes with rule, answersNodes WHERE Size([(rule)--(a:Answer) | a]) = SIZE(answersNodes) return distinct rule` – Matan Avitan Dec 07 '21 at 11:06
  • yes you are right, I overlooked that case. I did a second try – Graphileon Dec 07 '21 at 11:32
  • look like "ALL" function not support on neptune, I am using the latest version 1.1.0.0.R1, (the error: 'all' predicate function is not supported.) do you have another option for that? – Matan Avitan Dec 07 '21 at 11:59
  • it is very strange, didn't see in their documentations that it is not supported: https://docs.aws.amazon.com/neptune/latest/userguide/access-graph-opencypher-limitations.html – Matan Avitan Dec 07 '21 at 12:03
  • well, you tagged your question with 'neo4j' please note that openCypher on Neptune is still quite limited. See also https://docs.aws.amazon.com/neptune/latest/userguide/access-graph-opencypher-limitations.html – Graphileon Dec 07 '21 at 12:03
  • They mention the restrictions , as in the parts of openCypher they did not implement. AFAIK openCypher does not have ALL() according to https://s3.amazonaws.com/artifacts.opencypher.org/openCypher9.pdf – Graphileon Dec 07 '21 at 12:08
  • yea, I tagged it neo4j because this the package I use to run the query on python... there is option to find other way to do that? – Matan Avitan Dec 07 '21 at 12:08
  • I think that maybe we can do a query like the first option you gave, and check in the where statement if the size is equal to aNodes or equal to 0, and this will pass it, but can't create the whole query, all the time get exceptions... – Matan Avitan Dec 07 '21 at 12:43
  • yes, that would be an option. I cannot reproduce the errors, it must be some AWS neptune quirck. – Graphileon Dec 07 '21 at 12:49