How to do to cypher dsl with set += - cypher-dsl

I'am trying to use cypher dsl to create a Statement which results in
merge(n:entity {name:'value'}
set n += {k1:'v1',k2:'v2'}
return n
I parsed it with the CypherParser and it is oke. I see that the set clause has a mutate operator which , i quess, handles the '+='. But when i try to create it with the cypher dsl api i can't find how to express the '+='
Without '+=' the cypher dsl is something like:
var node = Cypher.node("entity").withProperties("name", Cypher.literalOf("value"))
var expression = Cypher.mapOf("k1", Cypher.literalOf("v1"), "k2", Cypher.literalOf("v2")
var statement = Cypher.merge(node).set(expression).returning(node).build()
This will result in : merge(n:entity {name:'name'} set n = {k1:'v1',k2:'v2'} return n.
The name property is gone when executing this query.
How can i express the '+=' in cypher dsl?
thanks

Related

Neo4J - Test nodes on path with unknown depth, with MATCH only

I want to test all nodes in the path from node a to node b (with only MATCH statement), where the depth is changing (could be any number). In the example below the depth is 2.
START a = node(86)
MATCH p0 = a-[*..2]-b
WHERE (b.attr = 'true') AND (a.attr = 'true')
RETURN p0
My question is how do I test the nodes between a and b for a certain attribute (attr = 'true'), using the MATCH statement, without knowing the depth required.
I find that using filter method I can filter out all the unwanted nodes.
like:
START a = node(86)
MATCH p0 = a-[*..2]-b
RETURN filter(x IN nodes(p0) WHERE x.attr = 'true')
But that is not what I need, I need to use MATCH.
Take a look at the Cypher refcard, specifically to the List Predicates section. The all() function should do the trick.
Something like:
START a=node(86)
MATCH p0=(a)-[*..2]-(b)
WHERE ALL(node in nodes(p0) WHERE node.attr = true)
RETURN p0
This will only match patterns where all the nodes in the pattern have that attribute as true.

Inconsistent cypher query results in neo4j

For illustrating this issue, create thousand nodes labeled z having incrementing numeric attribute zid.
FOREACH (i IN range(1, 1000)| CREATE (z:z { zid: i }));
Now find a node using random zid value between 1 and 1000.
MATCH (n:z { zid: round(rand()*1000)})
RETURN n;
The above cypher returns inconsistent results, sometimes no nodes are returned, sometimes multiple nodes are returned.
Tweaking the cypher as follows yields consistent results.
WITH round(rand()*1000) AS x
MATCH (n:z { zid: x })
RETURN x, n;
What is wrong with the first cypher query ?
The reason why you are receiving inconsistent results with the first query has to do with how Neo4j evaluates Cypher queries. The function round(rand()*1000) is evaluated for each of the items within the label index for z when using WHERE or concise syntax. When you use the WITH clause, the function is evaluated once.
That being said, this looks like a bug that is specific to the rand() function.

Iterating through a collection with MATCH and CREATE clauses

I want to do something like this in cypher:
MATCH (n:node) WHERE n.ID = x //x is an integer value
FOREACH (num in n.IDs:
MATCH (p:node) WHERE p.ID = num
CREATE (n)-[:LINK]->(p) )
where num is an array of integer values referring to the IDs of nodes that need to be linked to the node matched in the first line.
When I run this query, I get the error: Invalid use of MATCH inside FOREACH.
I'm in the early stages of teaching myself both Cypher and Neo4j. How can I achieve my desired functionality here? Or am I barking up the wrong tree - am I failing to grasp something that makes it unnecessary for me to do so?
This is not allowed, instead use the top-level MATCH like http://gist.neo4j.org/?8332363
MATCH (n:node), (p:node)
WHERE n.ID = 1 AND p.ID in [2,3,4]
CREATE (n)-[:LINK]->(p)

using set clause in spring cypher query

please provide me some example to use set clause in cypher query using java.
i just want to update property of relationship object but it always fail.
if i am running query like
ExecutionResult executionResult = engine.execute("start n=node:Person(name=\"suresh\"),n2=node:Email(subject=\"Hi\") match (n)-[r]-(n2) return r ");
System.out.println(executionResult);
i am getting proper response like below
+-----------------------------------------------------------------------------------------------------------------------------+
| r |
+-----------------------------------------------------------------------------------------------------------------------------+
| :DynamicRelationshipType[Have][69] {accessed->true,__type__->"org.test.spring.neo.domain.EmailRelationShip",relation->"To"} |
+-----------------------------------------------------------------------------------------------------------------------------+
1 rows, 260 ms
but when i am trying to run query like
start n=node:Person(name=\"suresh\"),n2=node:Email(subject=\"Hi\") match (n)-[r]-(n2) CREATE SET r.accessed=true return r
it always fail
stack Trace
expected return clause
"start n=node:Person(name="suresh"),n2=node:Email(subject="Hi") match (n)-[r]-(n2) CREATE SET r.accessed=true return r "
^
at org.neo4j.cypher.internal.parser.v1_6.CypherParserImpl.parse(CypherParserImpl.scala:65)
at org.neo4j.cypher.CypherParser.parse(CypherParser.scala:42)
at org.neo4j.cypher.ExecutionEngine$$anonfun$prepare$1.apply(ExecutionEngine.scala:60)
at org.neo4j.cypher.ExecutionEngine$$anonfun$prepare$1.apply(ExecutionEngine.scala:60)
at org.neo4j.cypher.internal.LRUCache.getOrElseUpdate(LRUCache.scala:31)
at org.neo4j.cypher.ExecutionEngine.prepare(ExecutionEngine.scala:60)
at org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:54)
at org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:51)
at org.neo4j.cypher.javacompat.ExecutionEngine.execute(ExecutionEngine.java:63)
at org.test.spring.neo.controller.MediatorController.main(MediatorController.java:34)
i tried to execute like below also but this one is also failing
ExecutionResult executionResult = engine.execute("start n=node:Person(name=\"suresh\"),n2=node:Email(subject=\"Hi\") match (n)-[r]-(n2) SET r.accessed=false return r ");
i am referring http://docs.neo4j.org/refcard/1.9/ to create a read and write query
i am using sdn version 1.8.
Please Help
As the error message says: "expected return clause"
Neo4j 1.8 is more restricted than e.g. 2.0
e.g. something like this works:
start n=node:Person(name="abc"), n2=node:Email(subject="Hi")
match (n)-[r]-(n2)
set r.accessed=true
return count(*)
You should also always use parameters:
start n=node:Person(name={person}), n2=node:Email(subject={subject})
match (n)-[r]-(n2)
set r.accessed=true
return count(*)

Py2neo cypher query return instance method

Using the py2neo tutorial (http://book.py2neo.org/en/latest/cypher/):
from py2neo import neo4j, cypher
graph_db = neo4j.GraphDatabaseService()
query = "START a=node(1) RETURN a"
data, metadata = cypher.execute(graph_db, query)
a = data[0][0] # first row, first column
Trying to replicate this, I get:
>data[0][0]
Node('http://localhost:7474/db/data/node/1')
How do I get this to return the actual data, instead of the abstract information?
Your Cypher query returns a node (RETURN a) and so that's what's being passed back: a Node object. If it's the node's properties that you need, you can either then inspect the properties on that node with the get_properties method or return specific properties from the Cypher query instead (RETURN a.name).

Resources