14

I have the following graph as a Neo4j graph database:

                           activates
                            (80 °F)
          (A)------------------------------------->(D)
           | \__                                _/->^
           |    \__  activates               __/    |
           |       \__(50 °F)             __/       |
           |          \__              __/          |             
           |             \__        __/             | 
activates  |                \__  __/                |
 (50 °F)   |                   \/                   | activates
           |                 __/\__                 | (50 °F)
           |    activates __/      \__              |
           |    (60 °F)__/            \__           |
           |        __/                  \__        |
           |     __/                        \__     |
           |  __/                              \_   |
           v /                                   \->|
          (B)------------------------------------->(C)
                           activates                          
                            (50 °F)

Each relationship has a property denoting the required temperature for the 'activates' action.

I need to retrieve all the available paths between (A) and (D) WHERE the temperature is 50 °F along the path.

The output should include:

A -[:activates{temperature:'50'}]-> B -[:activates{temperature:'50'}]-> C -[:activates{temperature:'50'}]-> D

A -[:activates{temperature:'50'}]-> C -[:activates{temperature:'50'}]-> D

but not

A -[:activates{temperature:'80'}]-> D

A -[:activates{temperature:'50'}]-> B -[:activates{temperature:'60'}]-> D

How do I write the required Cypher query?

Thanks in advance.

Edit 1: I added another diagonal relationship (B -[:activates{temperature:'80'}]-> D) for more clarity.

Edit 2: I need to retrieve all the available paths between (A) and (D) WHERE the temperature is the same along the path, i.e: A -> B -> C -> D, A -> C -> D, A -> D.

5
  • What have you tried so far? This can be done in cypher, but we'd like to see that you have tried something rather then just give you the solution outright. Commented Dec 31, 2012 at 19:23
  • My thought is to retrieve all the possible paths, then choose only the uniform paths using a Java code. But I think Cypher query can help in this scenario. Commented Dec 31, 2012 at 22:30
  • docs.neo4j.org/chunked/stable/… Commented Jan 1, 2013 at 2:24
  • 1
    just do an examples graph to play around with at console.neo4j.org? Commented Jan 2, 2013 at 14:37
  • Here is an example console.neo4j.org/?id=is8ao2. I modified it so it describes my scenario more accurately. In short, I need to find all paths from A to D where all the parts (relationships) of the matched path should have the same property. The result should include A -> B -> D (where temp = 50 along the path) -and- A -> C -> D (where temp = 60 along the path). Please see the "bus scenario" in my comment to ulkas (below). Commented Jan 3, 2013 at 10:15

1 Answer 1

18
START a=node({A}), d=node({D})
MATCH p=a-[r:ACTIVATES*..]-d
WHERE has(r.temperature) and r.temperature='50'
RETURN p;

substitute the values in the curved brackets (A,D) with their node IDs

update: using function all

START a=node(1), d=node(4) 
MATCH p=a-[r:ACTIVATES*..]-d 
WITH head(relationships(p))as r1,p //since the pointer r is a collection of rels we must declare a single relationship pointer
WHERE all(r2 in relationships(p) 
          where r2.temperature=r1.temperature) 
return p;
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you ulkas. Your answer completely answers the above scenario. However, I realized that the scenario should be more complex: all the relationships in one path should have common properties (temp=50 OR 60 OR ...), whatever they are. It is similar to bus paths, where you can travel from A to B via paths each of which is used by only one bus--whatever it is. If you think I need to post the modified scenario as a new question, I can gladly accept your answer here. ;)
This is cool, I wonder if it can be expanded into more general logic. It lends itself perfectly to the paths / arcs problem, obviously, but more general logic (along the lines of prolog) so if I have an 'is' relationship and if one node 'is' another, then it 'has' all the edges of the other node so edge(a,p,b) :- (a)-[:p]->(b) edge(a,p,b) :- (a)-[ :is* ]->( x ) AND (x)-[:p]>(b) But this of course could theoretically become a lot more general. I dont know if it's clear what I'm trying to say... I'm not very communicative today
For neo4j 3.4 I used this: MATCH p=(a:Database)-[r:PARENTS*..]-(d:Database) WHERE a.membershipID = 'H1001' and d.membershipID = "H12412" RETURN p;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.