Trying to make a Cypher request which should create (or merge) files and create a relationship to a given root Folder (which may doesn't exists yet). There is a uniquness constraint on :FILE(fullpath) and :FOLDER(fullpath). The Code I have written looks like this:
async public void createFiles(File[] files, Folder rootFolder)
{
var query = client.Cypher
.Merge("(root:FOLDER {fullpath: {newRoot}.fullpath})")
.Merge("(file:FILE {fullpath : {newFiles}.fullpath})")
.Set("file = {newFiles}")
.CreateUnique("root -[:CONTAINS]->(file)")
.WithParam("newFiles", files)
.WithParam("newRoot", rootFolder)
.ReturnDistinct<int>("0");
await query.ResultsAsync;
}
But it throws an Neo4jClient.NeoException: ThisShouldNotHappenError: Developer: Andres claims that: Need something with properties
exception.
I think the Exception is thrown by the second .Merge
. Isn't it possible to merge multiple nodes with an array as parameter?
Is it a bug or is it my smelling code?
neo4j 2.1.3
fadanner,
Assuming all of the underlying parts are present in the parameters, you can do what you want by changing your query to this:
var query = client.Cypher
.Merge("(root:FOLDER {fullpath : {newRoot}.fullpath})")
.ForEach("(newFile IN {newFiles} | MERGE (file:FILE {fullpath : newFile.fullpath}) SET file = newFile CREATE UNIQUE (root)-[:CONTAINS]->(file))")
.WithParam("newFiles", files)
.WithParam("newRoot", rootFolder)
.ReturnDistinct<int>("0");
I'm not a neo4jclient guy, so I may have some part of the syntax wrong, but this equivalent works with REST (at least I think its equivalent).
:POST /db/data/cypher
{"query":"MERGE (n:Foo {name : {prop1}.name}) FOREACH(prop IN {prop2} | MERGE (m:Goo {name : prop.name}) SET m = prop CREATE UNIQUE (n)-[:HAS]->(m))", "params":{"prop1":{"name":"cat"},"prop2":[{"name":"boo","gleek":"math"},{"name":"oob","gleek":"spit"}]}}
Grace and peace,
Jim