JnBrymn
JnBrymn

Reputation: 25373

Is it possible to determine if a Cypher MERGE results in a create or a match?

Consider the Neo4J 2.0 Cypher query

MERGE (u:User {id_str:"123"}) 
  ON CREATE SET
    u.name="Bob",
  ON MATCH SET
    u.phone_num="555-4152"
RETURN u

It's a silly query - don't worry about the intent here. The question is, how do I understand whether this query created or simply found a node?

UPDATE

Perhaps I should further motivate why I want this behavior. Here's why: If the node already exists, then don't have to go to a remote server (Twitter API in my case) and download all of the user's metadata. It would be nice if the ON CREATE could somehow link back out to a callback to pull down this data. It seems unlikely that this behavior is achievable in Cypher. So probably what I'll want to do is do a match, and if the get comes back NULL, then I'll call out to the Twitter API, get the metadata and do a create.

Upvotes: 3

Views: 2423

Answers (2)

jjaderberg
jjaderberg

Reputation: 9952

I think that's contrary to the intention of MERGE. You would use it to describe what you want the graph to look like after your query has executed, not to find out what it looks like before–read and write operations are supposed to be kept strictly apart in Cypher. That said, you can set a dummy property like @LameCoder mentioned:

MERGE (u:User {id_str:"123"}) 
  ON CREATE SET u.onCreate = true
WITH u, exists(u.onCreate) as onCreate
REMOVE u.onCreate
RETURN u, onCreate

will return (u), true if created, (u), false if not, and leave no side effects. Or you can maintain timestamps, perhaps one for node creation and one for when the node was last modified–I think that's an example from the documentation. This

MERGE (u:User {id_str:"123"}) 
  ON CREATE SET u.created = timestamp()
  ON MATCH SET u.lastModified = timestamp()
RETURN u, has(u.lastModified) as onMerge

would be similar to the query above.

Upvotes: 8

Juha M
Juha M

Reputation: 500

In Neo4j console, you may see that the query returns both summary and response. In Python, I check the result.summary().counters.nodes_created != 0.

Example: create a connected node with creation timestamp

query = """
    match (root:User {username:$root})
    merge (root) -[:HAS_ROOM]-> (r:Room {id:$rid})
        on create set r.timestamp = timestamp()
    return r"""
result = session.run(query, root=user, rid=role)
count = result.summary().counters.nodes_created 
record = result.single()   # Node data
if count > 0: print(f"Node {record['rp']} created")
else: print(f"Using an existing node {record['rp']}")

Upvotes: 4

Related Questions