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;
};
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'],[])