neo4j counting relations of multiple nodes - neo4j

I work on neo4j graph , I wrote this query
match (rec:Recipe) , (rec1:Recipe) , (rec)-[r:ContainsIngredient]->() , (rec1)- [r1:ContainsIngredient]->()
where rec.name = "a" AND rec1.name = "b"
return count(r) , count(r1)
it returns the same value , although Recipe("a") have three relations and Recipe("b") have 5 relations .
note : I noticed that it always returns the bigger value .

You aren't grouping by the recipe name. Try this:
MATCH (rec:Recipe)
WHERE rec.name = "a" OR rec.name = "b"
MATCH (rec)-[:ContainsIngredient]->()
RETURN rec.name, COUNT(*)

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

Using equals on different properties of the same collection returns no record, why?

When I use the following query:
MATCH (emp:Employee)
WHERE emp.supervisor_id = 159
RETURN emp
I get a result as 4 employees/nodes with supervisor_id = 159
and for this query I also get a result which is 1 employee with employeeID = 159 :
MATCH (emp:Employee)
WHERE emp.employeeID = 159
RETURN emp
But when I use the = operator, it does return (no changes, no records).
MATCH (emp:Employee)
WHERE emp.employeeID = emp.supervisor_id
RETURN emp
I assume it's a logic mistake, but I just can't figure it out.
Any idea pls.
In your query you are searching a node with the label Employee that has its attribute employeeID equals to supervisor_id.
Or from what I understand, what you want is to search two differents nodes with the label Employee.
So your query should be this one :
MATCH (emp1:Employee), (emp2:Employee)
WHERE emp1.employeeID = emp2.supervisor_id
CREATE (emp1)-[:MANAGER_OF]->(emp2)
This query create a Cartesian product, so if you have a lot of Employee nodes, you should batch the creation of relationships with an APOC procedure (https://neo4j-contrib.github.io/neo4j-apoc-procedures/) like this :
CALL apoc.periodic.iterate(
"MATCH (emp1:Employee) RETURN emp1",
"MATCH (emp2:Employee) WHERE emp1.employeeID = emp2.supervisor_id CREATE (emp1)-[:MANAGER_OF]->(emp2)",
{batchSize:5000, parallel:true}
);
Cheers

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)

Neo4j: Conditional return/IF clause/String manipulation

This is in continuation of Neo4j: Listing node labels
I am constructing a dynamic MATCH statement to return the hierarchy structure & use the output as a Neo4j JDBC input to query the data from a java method:
MATCH p=(:Service)<-[*]-(:Anomaly)
WITH head(nodes(p)) AS Service, p, count(p) AS cnt
RETURN DISTINCT Service.company_id, Service.company_site_id,
"MATCH srvhier=(" +
reduce(labels = "", n IN nodes(p) | labels + labels(n)[0] +
"<-[:BELONGS_TO]-") + ") WHERE Service.company_id = {1} AND
Service.company_site_id = {2} AND Anomaly.name={3} RETURN " +
reduce(labels = "", n IN nodes(p) | labels + labels(n)[0] + ".name,");
The output is as follows:
MATCH srvhier=(Service<-[:BELONGS_TO]-Category<-[:BELONGS_TO]-SubService<-
[:BELONGS_TO]-Assets<-[:BELONGS_TO]-Anomaly<-[:BELONGS_TO]-) WHERE
Service.company_id = {1} and Service.company_site_id = {21} and
Anomaly.name={3} RETURN Service.name, Category.name, SubService.name,
Assets.name, Anomaly.name,
The problem I am seeing:
The "BELONGS_TO" gets appended to my last node
Line 2: Assets<-[:BELONGS_TO]-Anomaly**<-[:BELONGS_TO]-**
Are there string functions (I have looked at Substring..) that can be used to remove it? Or can I use a CASE statement with condition n=cnt to append "BELONGS_TO"?
The same problem persists with my last line:
Line 5: Assets.name,Anomaly.name**,** - the additional "," that I need to eliminate.
Thanks.
I think you need to introduce a case statement into the reduce clause something like this snippet below. If the node isn't the last element of the collection then append the "<-[:BELONGS_TO]-" relationship. If it is the last element then don't append it.
...
reduce(labels = "", n IN nodes(p) |
CASE
WHEN n <> nodes(p)[length(nodes(p))-1] THEN
labels + labels(n)[0] + "<-[:BELONGS_TO]-"
ELSE
labels + labels(n)[0]
END
...
Cypher has a substring function that works basically like you'd expect. An example: here's how you'd return everything but the last three characters of a string:
return substring("hello", 0, length("hello")-3);
(That returns "he")
So you could use substring to trim the last separator off of your query that you don't want.
But I don't understand why you're building your query in such a complex way; you're using cypher to write cypher (which is OK) but (and I don't understand your data model 100%) it seems to me like there's probably an easier way to write this query.

Cypher query produces incomplete results (neo4j-1.9-SNAPSHOT)

I have run into the problem when executing a cypher query against a database "neo4j-1.9-SNAPSHOT" on Windows 7.
The database can be downloaded from the topic in Google Groups.
When I run the fist 2 queries in the web admin console, I do not get node with id ="45" as the first node in the path in the result list.
1) start a = node:my_nodes(label='2826'), b = node:my_nodes(label='2826')
match a-[r1]-b
with a, b, r1
match b-[r2]-c
where c.label = 2826 and r1.label = r2.label and id(r1) <> id(r2)
return id(a), id(b), id(c), id(r1), id(r2);
2) START n0=node:my_nodes(label='2826'), n1=node:my_nodes(label='2826'),
n2=node:my_nodes(label='2826')
MATCH n0-[r0]-n1-[r1]-n2
where r0.label = r1.label and id(r0)<>id(r1)
RETURN id(n0), id(n1), id(n2), id(r0), id(r1);
However, when I run the 3rd query, node with id="45" should definitely be in the result list of the first two queries. Moreover, when checking the database it seems to be the case.
3) start a = node(45), b = node:my_nodes(label='2826')
match a-[r1]-b
with a, b, r1
match b-[r2]-c
where a.label = 2826 and c.label = 2826 and r1.label = r2.label and id(r1) <> id(r2)
return id(a), a.label, id(b), id(c), id(r1), id(r2);
On running the cypher query:
start a = node:my_nodes(label='2826')
return id(a);
node with id="45" is in the index.
Any ideas what can be wrong with the first 2 queries?

Resources