Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
01-17-2022 04:57 AM
Hello All,
I'm learning data modelling my creating an express app in javascript and facing a few issues. For node and express linting isn't provided to highlight syntax errors. Could you please point me to the mistake in the below code?
create (m:Message{msg:$msg}) match (u1: User),(u2:User) where u1.id=$fromUserId and u2.id=$toUserId create (u1)-[s:SENT]->(m)-[b:SENT_TO]->(u2)
Thanks,
Arun
Solved! Go to Solution.
01-22-2022 10:41 AM
that explains it. the 'id' in your match statement is a user defined property of 'id.' It's not the same as the node id. If you want to search based on the node's id, then you need to reference it with 'id(n)', where n is the node.
MATCH (u:User where id(u) = $senderId), (v:User where id(v) = $receiverId)
or
MATCH (u:User), (v:User)
where where id(u) = $senderId and id(v) = $receiverId
01-17-2022 05:21 AM
Hello @arunkumar413
MATCH (u1:User {id: $fromUserId})
MATCH (u2:User {id: $toUserId})
CREATE (u1)-[:SENT]->(:Message {msg: $msg})-[:SENT_TO]->(u2)
Regards,
Cobra
01-17-2022 06:38 AM
Should we use compulsorily use match two times here. Can't we go with the comma operator to refer to the same nodes?
MATCH (u1:User {id: $fromUserId}), (u2:User {id: $toUserId})
In my code I'm first creating a message and getting it's reference as m
and using it in CREATE
statement. It's looks valid. Any explanation on why my code didn't work would be of great help.
01-17-2022 06:58 AM
In this context both queries do the same thing. The comma becomes important when you are traversing relationships. A relationship will only be traversed once per MATCH
. Say you had a graph with:
CREATE (:Person {name: "Tom Hanks"})-[:ACTED_IN]->(m:Movie {title: "The Green Mile"}),
(:Person {name: "Michael Clarke Duncan"})-[:ACTED_IN]->(m)
Running this query wouldn't return Tom Hanks in the result set:
MATCH (:Person {name: "Tom Hanks"})-[r1:ACTED_IN]->(m:Movie {title: "The Green Mile"})),
(m)<-[r2:ACTED_IN]-(p)
RETURN p
Because r1
would never be included in r2
.
However, adding another MATCH
means the relationship would be traversed as part of the second clause:
MATCH (:Person {name: "Tom Hanks"})-[r1:ACTED_IN]->(m:Movie {title: "The Green Mile"}))
MATCH (m)<-[r2:ACTED_IN]-(p)
01-21-2022 05:13 AM
Actually the query isn't working
01-17-2022 06:43 AM
Maybe the space between the :
and User
in the match in your query.
01-20-2022 09:51 AM
:
is a valid delimiter.
01-17-2022 09:31 AM
You can't mix match and create without 'with' clause. The editor gives this warning.
match (u1:User)
match (u2:User)
where u1.id=$fromUserId and u2.id=$toUserId
with u1, u2
merge (u1)-[:SENT]->(:Message{msg:$msg})-[:SENT_TO]->(u2)
You want to use 'merge' to create the path, as create will create it again if the query is repeated, i.e. each time it is run a new message node will be created and linked to the existing u1 and u2 nodes. Merge only adds the missing parts.
An alternative implementation to show further use of the 'with' clause:
merge (m:Message{msg:$msg})
with m
match (u1:User)
match (u2:User)
where u1.id=$fromUserId and u2.id=$toUserId
with m, u1, u2
merge (u1)-[:SENT]->(m)-[:SENT_TO]->(u2)
I used 'merge' with the message node, so it only gets created once if the query is executed multiple times.
01-20-2022 07:46 AM
I'm trying to follow this example which doesn't contain any merge and with clause.
MATCH
(a:Person),
(b:Person)
WHERE a.name = 'A' AND b.name = 'B'
CREATE (a)-[r:RELTYPE]->(b)
RETURN type(r)
01-21-2022 06:55 AM
Will the below code work?
MATCH (u: User {id: $senderId}), (v: User{id:$receiverId})
CREATE(m:Message{msg:$msg})
CREATE(u)-[s1:SENT]->(m)-[s2:SENT_TO]->(v)
01-20-2022 10:34 AM
The ':' is used to specify the node or relationship type, i.e., Person and RELTYPE in your example.
The author of this cypher statement assumes that nodes a and b exist in the database. If not, either or both match clauses would return null (if a or b or both are missing), thus terminating the query.
Using the create clause in the pattern, will cause the relationships to be created regardless of its existence, thus it gets created each time the query is executed.
You can rewrite the query using merge clause, so redundant data is not created
MERGE (a:Person{name:'A'})
MERGE (b:Person{name:'B'})
MERGE (a)-[r:RELTYPE]->(b)
RETURN type(r)
Or, in one statement:
MERGE (a:Person{name:'A'})-[r:RELTYPE]->(b:Person{name:'B'})
RETURN type(r)
Neo4j Desktop complains that 'with' is required between either 'create' and 'merge' and a following 'match.' It would seem that create and merge are considered terminal statements, so a with clause is required to chain more cypher, by passing previous results to the next cypher block. That being correct, the query posted earlier does not require the second 'with' clause, .i.e., 'with m, u1, u2.' The statement executes fine without it. The cypher query does require the 'with m' clause, as the merge can't be followed with a match without a separating 'with' clause.
01-21-2022 05:15 AM
`MATCH (u: User {id: $senderId}), (v: User {id: $receiverId})` User exists in the database.
01-21-2022 07:25 AM
Yes, as you don't need the 'with' clause between a match followed by a create. You need it when transitioning from a create/merge to a match.
Note, the use of create clauses will cause the message node and the relationships to be created each time the query is run. It is safer to use merge to avoid redundant data, unless you are sure in your use case that the items don't already exist.
01-21-2022 07:29 AM
Thanks. Is it possible to disable duplicate or enforce only single relationship of a type?
01-21-2022 07:51 AM
You can create uniqueness constraints by label and property.
01-21-2022 07:53 AM
Just tried this query in on my local machine. It executes but the message node and it's relationships aren't created
01-21-2022 08:00 AM
Are both match nodes in the database?
01-21-2022 08:39 AM
Yes, they exist before I ran this query.
01-21-2022 10:39 AM
That is unexpected. I tested it myself. To verify, execute the two match statements separately to verify that results are returned by each.
01-22-2022 06:45 AM
Even match isn't working. Is it because of trying to match with the ids created by system?
01-22-2022 10:41 AM
that explains it. the 'id' in your match statement is a user defined property of 'id.' It's not the same as the node id. If you want to search based on the node's id, then you need to reference it with 'id(n)', where n is the node.
MATCH (u:User where id(u) = $senderId), (v:User where id(v) = $receiverId)
or
MATCH (u:User), (v:User)
where where id(u) = $senderId and id(v) = $receiverId
01-23-2022 06:38 AM
Thanks all for all the help.
All the sessions of the conference are now available online