Search code examples
neo4jgraph-databasesgraphenedb

How to add unique data to a neo4j graph database


I am adding iteratively data to my neo4j database but I am stuck with how to overwrite or update existing data and to check whether the data does not already exist in there.

Basically I have a set of movies with their corresponding id's, e.g.:

[
  {id: 'gameofthrones', genre: 'fantasy', release: '2017'},
  {id: 'inception', genre: 'scifi', release: '2010'},
  ...
]

I can add the movies as follows:

CREATE 
(m1:Movie {id: 'gameofthrones', genre: 'fantasy', release: '2017'}), 
(m2:Movie {id: 'inception', genre: 'scifi', release: '2010'}) 

However, when I run the script two times, then it creates 4 nodes instead of keeping it at two nodes.

So my question is, how can I make sure that it checks whether the node id is already present, and if so overwrite it instead of creating a new node?

I tried (but only the properties get added)

// data
attributes['id']         = 'gameofthrones';
attributes['genre']     = 'fantasy';
...

// query
MERGE ( s:Movie {attributes}.id)
ON CREATE SET ( s:Movie {attributes} )

which I call in NodeJS as follows:

executeQuery(queryStr, {"attributes": attributes})

// cypher (nodejs)
function executeQuery(queryStr, params) {
    var qq = Q.defer();
    db.cypher({
        query: queryStr,
        params: params,
    }, function (error, results) {
        if (error) {
            qq.reject(error);
        } else {
            if (results.length != 0) {
                qq.resolve(true);
            } else {
                qq.resolve(false);
            }
        };
    });
    return qq.promise;
};

Solution

  • you must change your query to this

    MERGE ( s:Movie {attributes}.id)
    ON CREATE SET s += {attributes}
    ON MATCH SET s += {attributes} // optional
    

    this should work, but you should use apoc.map.clean() so you do not set the id twice, which can cause some problems.

    MERGE ( s:Movie {attributes}.id)
    ON CREATE SET s += apoc.map.clean({attributes},['id'],[])