Cypher UNION query - neo4j

I have the simple following graph:
http://console.neo4j.org/?id=v0cvwn
And I wonder why the following query:
START n=node(2)
match n-[:KNOWS]-node
return node.name as name
UNION
START n=node(2)
match n-[:ACTS_IN]-node
return node.name as name
throws an exception:
java.lang.AssertionError: assertion failed: Can't profile the same pipe twice
at scala.Predef$.assert(Predef.scala:179)
at org.neo4j.cypher.internal.profiler.Profiler.decorate(Profiler.scala:47)
at org.neo4j.cypher.internal.pipes.Pipe$class.createResults(Pipe.scala:35)
at org.neo4j.cypher.internal.pipes.NullPipe$.createResults(Pipe.scala:47)
at org.neo4j.cypher.internal.pipes.PipeWithSource.createResults(Pipe.scala:61)
at org.neo4j.cypher.internal.pipes.PipeWithSource.createResults(Pipe.scala:61)
at org.neo4j.cypher.internal.pipes.PipeWithSource.createResults(Pipe.scala:61)
at org.neo4j.cypher.internal.pipes.UnionIterator.loadNextIterator$1(UnionIterator.scala:60)
at org.neo4j.cypher.internal.pipes.UnionIterator.step$1(UnionIterator.scala:68)
at org.neo4j.cypher.internal.pipes.UnionIterator.stepIfNeccessary(UnionIterato
Couple of questions regarding UNION:
Is it possible to perform another final match clause on all the data which was accumulate in the result set as a result from the UNION in previous sub-queries?
Is it possible to perform an order by on that data?
Thanks.

According to these github comments, UNION is only support in version 2.0 or higher.
https://github.com/neo4j/neo4j/issues/125

Related

Adding New Relationships in Neo4j Database using apoc.periodic.iterate

I have a Neo4j database with two kinds of nodes - Authors and Articles. Some of the articles have more than one author. I am trying to create an undirected relationship between the authors who worked together on an article. My current non-functional query is this:
CALL apoc.periodic.iterate(
"MATCH (a:Author) WHERE (a)-[:WROTE]->()<-[:WROTE]-(b:Author) RETURN a,b",
"WITH {a} AS a, {b} as b CREATE (a)-[r:COAUTHOR]-(b)", {batchSize:10000, parallel:true})
I get the following error:
Failed to invoke procedure apoc.periodic.iterate: Caused by: org.neo4j.exceptions.SyntaxException: PatternExpressions are not allowed to introduce new variables: 'b'. (line 1, column 60 (offset: 59))
"EXPLAIN MATCH (a:Author) WHERE (a)-[:WROTE]->()<-[:WROTE]-(b:Author) RETURN a,b"
I can see that the issue is that I am trying to do too much in the first MATCH statemetn, but I'm new to Cypher and am having trouble breaking it up.
Thanks very much,
John
The problem stems from your first statement:
MATCH (a:Author)
WHERE (a)-[:WROTE]->()<-[:WROTE]-(b:Author)
RETURN a,b
Cypher does not allow introducing new variables on the WHERE part of the query, so your (b:Author) will not be allowed since it's located on the WHERE clause.
To fix, move (b:Author) to the MATCH statement. Also, if you are finding a pattern on the WHERE clause, you should use the exists() function in order to return a boolean.
MATCH (a:Author), (b:Author)
WHERE exists((a)-[:WROTE]->()<-[:WROTE]-(b))
RETURN a, b

How to make MATCH result mandatory with Cypher?

I have a cypher looking like this:
CREATE
(a:LabelA {
uid: "01"
})
WITH * MATCH
(b:LabelB {uid: "02"})
MERGE (a)-[:RELATION]->(b)
If I do not have any node with uid "02" I would like to get an error. This cypher passes, but the relation (a)-[:RELATION]-(b) is not created (since the node 'b' does not exist).
How can I solve this?
Ter is no way to get error with your scenario if you are directly executing this query on neo4j. In case you are executing this query through some application via an API, then probebly you can write functionality to throw exception.
It is not an error for a MATCH pattern to not match anything.
If your code needs an error for some reason, then it should just generate an error when the query response indicates that there is no node with a uid value of "02".
For example, suppose you added an appropriate RETURN statement to your query:
MERGE (a:LabelA {uid: "01"})
WITH *
MATCH (b:LabelB {uid: "02"})
MERGE (a)-[:RELATION]->(b)
RETURN b;
Then, your code can check if any data rows are returned. If no rows are returned, then there is no node with the uid value "02".

How to update Nodes within a random manner in Neo4j

how can i update a random set of nodes in Neo4j. I tried the folowing:
match (Firstgraph)
with id(Firstgraph) as Id
return Firstgraph.name, Firstgraph.version,id(Firstgraph)
order by rand();
match (G1:FirstGraph)
where id(G1)=Id
set G1.Version=5
My idea is the get a random set then update it, but i got the error:
Expected exactly one statement per query but got: 2
Thanks for your help.
Let's find out what's the problem here, first of all, your error
Expected exactly one statement per query but got: 2
This is coming from your query, if we check it, we see that you did two queries in the same sentence, that's why you get this error.
match (Firstgraph) with id(Firstgraph) as Id
return Firstgraph.name, Firstgraph.version,id(Firstgraph) order by
rand(); match (G1:FirstGraph) where id(G1)=Id set G1.Version=5
This is not a good query, because you can't use ; in a query sentence, it's the query end marker, so you can't do another query after this, but you can use UNION:
match (Firstgraph) with id(Firstgraph) as Id
return
Firstgraph.name, Firstgraph.version,id(Firstgraph) order by rand()
UNION
match (G1:FirstGraph) where id(G1)=Id set G1.Version=5
Also, if you want to match a random set of nodes, you can simply do this (this example is for a 50% chances to get each node):
Match (node) Where rand() > 0.5 return node
And then do whatever you want with the node using WITH

Post processing on UNION result cypher query neo4j

I have written below query using lucene indexing . I know UNION doesn't have pagination support in neo4j . I want to post process the
final result of this query to paginate the result .
START user=node:peopleSearch('username:abhay*') RETURN user , user.createdDate as time UNION START rel= Relationship:peopleSearch('skillName:Java23') RETURN StartNode(rel) as user , StartNode(rel).createdDate as time
I have followed this link . But it giving me error on UNION RESULT .
I need to post process the union final result to paginate it
The referenced github issue is not yet resolved, so post processing of UNION is not yet possible.
As a workaround in the meantime you can split up your query into two queries. The first one combines the index lookups and returns node ids:
START user=node:peopleSearch('username:abhay*') RETURN id(user) as id
UNION
START rel= Relationship:peopleSearch('skillName:Java23') RETURN id(StartNode(rel)) as id
On client side, collect the returned IDs into an array and submit the second query using a cypher parameter:
MATCH (n)
WHERE ID(n) IN {myIdArray}
WITH n
// placeholder for rest of this query
where the parameter value of myIdArray is the returned IDs from step1.
I had a similar question a few weeks ago, and it turns out Cypher currently does not support post-UNION processing.
This means that you should filter both inputs of the union using the same condition.
Alternatively (as mentioned in this answer), if you can use APOC, you can post-process the results of a query:
CALL apoc.cypher.run("... UNION ...", NULL) YIELD n, r, x
WHERE ...
RETURN n, r, x;
Update: this is now possible in Neo4j 4.0 using the CALL {subquery} construct.

What is the appropriate cypher query?

I am trying to run the web ui on
7474/webadmin/#
Suppose I want to find a node that has a property "title" with a value of "Home".
How do I find that node using a cypher query? (There should be only one node.)
Also, suppose I want to retrieve a relationship?
Let's say I have the following:
A -entitledTo-> B -entitledTo-> C
I have already tried the following:
start n=node(*) where n.title='Home' return n;
start c=node(node_c_id) match a-[:entitledTo]->b-[:entitledTo]->c return a,b,c;
However, I get this error message: The property 'title' does not exist on Node[0]
How do I resolve this issue?
Lastly, this is version 2.0.0-M03
use:
start n=node(*) where has(n.title) and n.title='Home' return n
In general you should consider using indexes for this kind of operation, Neo4j's reference manual has lots of information about this.
You can use:
start n=node(*) where n.title! ='Home' return n;
See the section on missing properties in where clauses
To retrieve the Relationships, perhaps the Cypher PATH command could be usefull.

Resources