Search code examples
c#neo4jneo4jclient

Creating Node and Edge in Neo4j on Certain Conditions


I'm currently trying to add a list of unique locations into Neo4j (merge). If a Location node has a value for OwnerId, then I would like to create a relation to the matching Owner node and add a new label called ManagedLocation.

Example

public class Location
{
    public string Name {get;set;}
    public string Built {get;set;}
    public long OwnerId {get;set;}
}

public class Owner
{
    public long Id {get;set;
    public string Name {get;set;}
}

The issue that I am having is that it's only adding those where OwnerId has a value and ignores the rest. The answer can either be coded with Neo4jClient, or raw CYPHER and I can work the rest out from there. Feel free to ask any questions for clarification

Here is what I have so far:

 graphClient.Cypher
                    .Unwind(locs, "loc")
                    .Match("(t:Owner{ Id: loc.OwnerId}) RETURN t LIMIT 1")
                    .Merge("(l:Location {Name: loc.Name})")
                    .OnCreate()                        
                    .Set("l = loc")
                    .Create("(t)-[:Manages]->(l)")
                    .Set ("l = ManagedLocation")
                    .ExecuteWithoutResults();

Solution

  • It's all to do with the ordering of your code, in cases where the OwnerId isn't set - the MATCH will fail - and so won't continue with the query. You have to do the MERGE on the location first:

    graphClient.Cypher
        .Unwind(locs, "loc")
        .Merge("(l:Location {Name: loc.Name})")
        .OnCreate()
        .Set("l = loc")
        .With("l")
        .Match("(t:Owner { Id: l.OwnerId})")
        .Create("(t)-[:Manages]->(l)")
        .Set("l:ManagedLocation")
        .ExecuteWithoutResults();
    

    As a side note - you might want the bottom .Create of the relationship to be a Merge as well - so you can run the query as many times as you want without creating duplicate relationships.