Neo4j aggregate function - neo4j

I am trying to use the SUM function and store the result of it as a new property of the relationship. But it is not working.
The query I used is :
MATCH (a:Employee)-[r:CorporateMessage]->(b)
WHERE a.Eid = 6001 AND b.Eid IN [6002,6003,6004,6005,5001]
SET r.Internalsum = SUM(r.Count)
The error i got was:
Invalid use of aggregating function sum(...) in this context (line 1, column 124 (offset: 123)) "MATCH (a:Employee)-[r:CorporateMessage]->(b)WHERE a.Eid = 6001 AND b.Eid IN [6002,6003,6004,6005,5001] SET r.Internalsum = SUM(r.Count)"
Kindly explain what i am doing wrong.

Try it:
MATCH (a:Employee)-[r:CorporateMessage]->(b)
WHERE a.Eid = 6001 AND b.Eid IN [6002,6003,6004,6005,5001]
WITH r, SUM(r.count) as count
SET r.Internalsum = count
Always put aggregation functions in WITH or RETURN.

Related

Unknown function 'org.neo4j.examples.join' on neo4j

I am trying to creating user defined procedure.
i got the sample project from this github repository https://github.com/neo4j-examples/neo4j-procedure-template. i created the jar file and moved to /var/lib/neo4j/plugins
i am getting the unknown function error
If anyone knows about it help me please
also i restarted my neo4j also
neo4j> MATCH (p: Person) WHERE p.age = 36 RETURN org.neo4j.examples.join(collect(p.names));
Unknown function 'org.neo4j.examples.join' (line 1, column 44 (offset: 43))
"MATCH (p: Person) WHERE p.age = 36 RETURN org.neo4j.examples.join(collect(p.names));"
If you look at the comment on the java method for this function, you will see into the description annotation, that to call it you should do : example.join(...) and NOT org.neo4j.examples.join.
This function is under the java package example, and the name of the function is join, so it gives you example.join
You can define manually what is the way to call a function by adding a name attribut into the UserFunction annotation. Like this :
#UserFunction( "test.nodeList" )
public List<Object> nodeList()
{
Result result = db.execute( "MATCH (n) RETURN n LIMIT 1" );
Object node = result.next().get( "n" );
return Collections.singletonList( node );
}
And call it in cypher like this :
RETURN test.toSet(['a', 'b'])

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.

Neo4j/Cypher: Setting a map and property yields "expected valid query body"

The following query fails:
MATCH n:User
WHERE n.email = "test"
SET n = {data}, n.created = timestamp()
RETURN n
Is this expected? Is it a bug? Is there a workaround? Do I have to compute the timestamp and send it along with {data}?
A slight modification of your statement using 2 SET clauses works:
MATCH n:User
WHERE n.email = "test"
SET n = {data}
SET n.created = timestamp()
RETURN n

Resources