Question

I'm using Neo4j 2.0.0-M06. Just learning Cypher and reading the docs. In my mind this query would work, but I should be so lucky...

I'm importing tweets to a mysql-database, and from there importing them to neo4j. If a tweet is already existing in the Neo4j database, it should be updated.

My query:

MATCH (y:Tweet:Socialmedia) WHERE
HAS (y.tweet_id) AND y.tweet_id = '123'
CREATE UNIQUE (n:Tweet:Socialmedia {
 body : 'This is a tweet', tweet_id : '123', tweet_userid : '321', tweet_username : 'example'
} )

Neo4j says: This pattern is not supported for CREATE UNIQUE

The database is currently empty on nodes with the matching labels, so there are no tweets what so ever in the Neo4j database.

What is the correct query?

Was it helpful?

Solution

You want to use MERGE for this query, along with a unique constraint.

CREATE CONSTRAINT on (t:Tweet) ASSERT t.tweet_id IS UNIQUE;

MERGE (t:Tweet {tweet_id:'123'})
ON CREATE
SET t:SocialMedia, 
    t.body = 'This is a tweet', 
    t.tweet_userid = '321', 
    t.tweet_username = 'example';

This will use an index to lookup the tweet by id, and do nothing if the tweet exists, otherwise it will set those properties.

OTHER TIPS

I would like to point that one can use a combination of

  1. CREATE CONSTRAINT and then a normal
  2. CREATE (without UNIQUE)

This is for cases where one expects a unique node and wants to throw an exception if the node unexpectedly exists. (Far cheaper than looking for the node before creating it).

Also note that MERGE seems to take more CPU cycles than a CREATE. (It also takes more CPU cycles even if an exception is thrown)

An alternative scenario covering CREATE CONSTRAINT, CREATE and MERGE (though admittedly not the primary purpose of this post).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top