To get all nodes and path from edge to root using neo4j - neo4j

I want to get all nodes information with paths from edge to root node.Using one of the edge property.
This is the three layer node structure.
MATCH (g:GrandChild{name:"C"})<-[:childToGrandChild]-(c:Child)<-[p:Parent*0..]-(c:Child) RETURN c,g,p
This will return only B,C nodes with relationship like this
cypher used
CREATE (p: Parent{name : '1'} ) RETURN p
MATCH (p:Parent) WHERE p.name = '1' CREATE (c: Child{name : '2'} )<-[:parentToChild]-(p) RETURN p
MATCH (c:Child) WHERE c.name = '3' CREATE (g: GrandChild {name : '2'} )<-[:childToGrandChild]-(c) RETURN c
Please help..

You have missed parentTochild relationship which will be like,
MATCH (g:GrandChild{name:"C"})<-[:childToGrandChild]-(c:Child)<-[parentToChild*0..]-(p:Parent)
RETURN c,g,p

Try this :
MATCH (g:GrandChild{name:"C"})<-[:childToGrandChild]-(c:Child)
MATCH (c)<-[p:Parent*0..]-(c2:Child)
RETURN c,c2,g,p

Related

How to query with two conditions in Neo4j

I am new with Neo4j and I am stucked trying to get a query with two conditions, where I want to get all the "Autors" related to "Pixar" and "Fox". So far I have tried the following two ways:
MATCH (a:Autor)- [:AUTOR_DE]-> (t:Título) -[:PRODUCIDO_POR] ->( p:Productora {Nombre: "Pixar"}),
and
MATCH (a:Autor)- [:AUTOR_DE]-> (t:Título) -[:PRODUCIDO_POR] ->( p:Productora {Nombre: "Fox"}),
return a,p
and
MATCH (a:Autor)- [:AUTOR_DE]-> (t:Título) -[:PRODUCIDO_POR] ->( p:Productora)
WHERE ( (p:Productora) = "Fox" OR (p:Productora) = "Pixar")
return a,p
Thanks in advance
Assuming that a Productora node stores its name in a name property, and that every Productora node has a unique name, this should work:
MATCH (a:Autor)-[:AUTOR_DE]->(:Título)-[:PRODUCIDO_POR]->(p:Productora)
WHERE p.name = "Fox" OR p.name = "Pixar"
WITH a, COLLECT(DISTINCT p) AS ps
WHERE SIZE(ps) = 2
return a, ps
And this should also work:
MATCH (fox:Productora), (pixar:Productora), (a:Autor)
WHERE fox.name = "Fox" AND pixar.name = "Pixar" AND
(a)-[:AUTOR_DE]->(:Título)-[:PRODUCIDO_POR]->(fox) AND
(a)-[:AUTOR_DE]->(:Título)-[:PRODUCIDO_POR]->(pixar)
return a, fox, pixar

How to check if node globally exists and set condition on it in Cypher?

I'm struggling with problem of creating query in Cypher.
Let's use this graph as an example:
MERGE(a:Person {name:'Alice', age:38, eyes:'brown'})
MERGE(c:Person {name:'Charlie', age:53, eyes:'green'})
MERGE(d:Person {name:'Daniel', age:54, eyes:'brown'})
MERGE(b:Person {name:'Bob', age:25, eyes:'blue'})
MERGE(a)-[:KNOWS]->(c)
MERGE(a)-[:KNOWS]->(b)
MERGE(c)-[:KNOWS]->(d)
MERGE(b)-[:KNOWS]->(d)
I would like to have query that returns me nodes with name = 'Alice' only if there aren't any nodes with name = 'Bob'. So if there is Bob I would like to see no results.
Here is what I've tried:
1) With exists()
MATCH p =(n)-[*1..3]->(b)
WHERE n.name = 'Alice' AND NOT EXISTS ((n {name: 'Bob'})-[*1..3]->(b))
RETURN p
But it returns all nodes and relationships.
2) With none()
MATCH p =(n)-[*1..3]->(b)
WHERE n.name = 'Alice' AND NONE (x IN nodes(p) WHERE x.name = 'Bob')
RETURN p
This returned all nodes, without Bob...
3) with any()
MATCH p =(n)-[*1..3]->(b)
WHERE n.name = 'Alice' AND NOT ANY (x IN nodes(p) WHERE x.name = 'Bob')
RETURN p
But this gave me the same result as above.
I'm running out of ideas how to return Alice only if Bob is not present.
What I would expect from query is to return Alice when I delete Bob, but when such node exists - nothing.
Any help is appreciated:)
Thanks!
You should try this query :
MATCH (n:Person {name:'Alice'})
WHERE NOT (n)-[:KNOWS*..3]-(:Person {name:'Bob'})
RETURN n

Neo4j - Cypher - Build object where Property is dynamic, like Type(r)

From my searchings I did not find a way to set the property of an object dynamically, only by defining it hardcoded (Like below the "Detail" property)
Here is my sample:
Neo4j Graph or via Neo4j Console
MATCH(p:Person)-[r]->(m:Movie)
WITH { Person: p.name,
Detail: collect(r.roles)
} AS Result
RETURN Result
My target (not working yet):
MATCH(p:Person)-[r]->(m:Movie)
WITH { Person: p.name,
CASTED_FOR: // --> Only values(r.roles) for relationship "CASTED_FOR" needed here
ACTED_IN: // --> Only values(r.roles) for relationship "ACTED_IN" needed here
} AS Result
RETURN Result
I know I could make e.g. [r:CASTED_FOR] or WHERE Type(r) = "CASTED_FOR", but I don't like to have multiple WITH and MATCH queries.
Thank you
This query uses Cypher's list comprehension construct to do what you want:
MATCH (p:Person)-[r]->(:Movie)
WITH p, COLLECT(r) AS rs
RETURN {
Person: p.name,
CASTED_FOR: [x IN rs WHERE TYPE(x) = 'CASTED_FOR' | x.roles],
ACTED_IN: [x IN rs WHERE TYPE(x) = 'ACTED_IN' | x.roles]
} AS Result

Neo4j: Creating Multiple Relationships Not Working

I am creating multiple relationships in one query. If a match is not found for the first relationship the second one is not created. If both matches exist then both relationships work.
Example:
Assume that 'MATCH1ID' below does not exist but 'MATCH2ID' does. Why does this happen?
DOES NOT WORK
MERGE (NewRecord:OBJECTNAME { Id: 'ABZDEFG' })
SET NewRecord.name='NEWNAME'
WITH NewRecord
MATCH (a)
WHERE a.Id = 'MATCH1ID'
CREATE (a)-[ar:Relationship1]->(NewRecord)
WITH NewRecord MATCH (b)
WHERE b.Id = 'MATCH2ID'
CREATE (b)-[br:Relationship2]->(NewRecord)
(If I switch the order of the node that does exist to be first in the order it works)
WORKS
MERGE (NewRecord:OBJECTNAME { Id: 'ABZDEFG' })
SET NewRecord.name='NEWNAME'
WITH NewRecord
MATCH (b)
WHERE b.Id = 'MATCH2ID'
CREATE (b)-[br:Relationship2]->(NewRecord)
WITH NewRecord
MATCH (a)
WHERE a.Id = 'MATCH1ID'
CREATE (a)-[ar:Relationship1]->(NewRecord)
You can try using a OPTIONAL MATCH instead of a simple MATCH:
MERGE (NewRecord:OBJECTNAME { Id: 'ABZDEFG' })
SET NewRecord.name='NEWNAME'
WITH NewRecord
OPTIONAL MATCH (a)
WHERE a.Id = 'MATCH1ID'
FOREACH(x IN (CASE WHEN a IS NULL THEN [] ELSE [1] END) |
CREATE (a)-[ar:Relationship1]->(NewRecord)
)
WITH NewRecord
OPTIONAL MATCH (b)
WHERE b.Id = 'MATCH2ID'
FOREACH(x IN (CASE WHEN b IS NULL THEN [] ELSE [1] END) |
CREATE (b)-[br:Relationship2]->(NewRecord)
)
Also, this query uses a trick with FORACH and CASE WHEN to handle conditions. In this case, the CREATE statement is executed only when a or b variables are not null.
See Neo4j: LOAD CSV - Handling Conditionals.

neo4j sum up values

I'm trying to get Total(Sum) of a property of "df" object.I have attached screen shot of sample database I'm using
I tried to get the graph using following query
MATCH P= (n:Org)-[:O_CH*0..]->()-[:LEAF*0..]->()-[:CH*0..]->()-[:FOR*0..]->() RETURN P
To create objects
create(n:Org{name:'Root',id:1})
create(n:Org{name:'L1.1',id:2,parent:1})
create(n:Org{name:'L1.2',id:3,parent:1})
create(n:Org{name:'L1.3',id:4,parent:1})
create(n:Org{name:'L2.1',id:5,parent:3})
create(n:Org{name:'L2.2',id:6,parent:4})
create(n:Op{name:'CH1',id:7,orgId:5})
create(n:Op{name:'CH2',id:8,orgId:5 ,parent:'CH1'})
create(n:Proj{name:'P1',id:9,opp:'CH2'})
create(n:Proj{name:'P2',id:10,opp:'CH1'})
create(n:R{name:'R1',id:200,orgId:2 })
create (n:df{id:100,map:8,forecast:toFloat(10)})
create (n:df{id:101,map:7,forecast:toFloat(10)})
create (n:df{id:102,map:9,forecast:toFloat(10)})
create (n:df{id:103,map:10,forecast:toFloat(10)})
create (n:df{id:104,map:200,forecast:toFloat(10)})
To Crate relationships
MATCH (c:Org),(p:Org) WHERE c.parent = p.id create (p)-[:O_CH]->(c)
MATCH (c:Op),(p:Op) WHERE c.parent = p.name create (p)-[:CH]->(c)
MATCH (c:Op),(p:Org) WHERE c.orgId = p.id create (p)-[:LEAF]->(c)
MATCH (c:Proj),(p:Op) WHERE c.opp = p.name create (p)-[:CH]->(c)
MATCH (c:R),(p:Org) WHERE c.orgId = p.id create (p)-[:LEAF]->(c)
MATCH (c:df),(p:) WHERE c.map = p.id create (p)-[:FOR]->(c)
I'm expecting 60 as total where I get 260 as total. Please let me know where I'm wrong . Need your help to figure out.
I'm trying to get Total(Sum) of a property of "df" object.
I believe you needs a simple query that match all nodes with label :df and return the sum of node.forecast. Try it:
// Match all nodes with :df label
MATCH(n:df)
// Return the sum of the property 'forecast' of each matched node
RETURN sum(n.forecast)
From comments:
Thank you Bruno.But the thing i need to get the aggregated value as a
example if i select L2.1 , i need to get the sum of df objects which
are under that node
This should work:
MATCH({name:'L2.1'})-[*]->(n)
RETURN SUM(n.forecast)

Resources