Search code examples
neo4jneo4jclient

How do I delete a relationship using Neo4jClient


Am trying to get the basics down before moving forward with neo4j. Love the querying aspect but now trying to delete using neo4jclient and stuck.

Simple setup
root-[:has_user]->user and user-[:friends_with]->friend`

For a user with the Id of 1 I would like to remove the specified from Id == 2. User 1 is no longer friends with User 2 :(

Anyway, using neo4jclient I first check to make sure that the users are friends in the first place with this:

if (client.Cypher.Start("root", client.RootNode)
    .Match("root-[:HAS_USER]->user-[:FRIEND]->friend")
    .Where((UserNode user, UserNode friend) => user.Id == 1 && friend.Id == id)
    .Return<Node<UserNode>>("user")
    .Results
    .Count() == 1)
{

now I'm trying to delete:

    client.Cypher.Start("root", client.RootNode)
        .Match("root-[:HAS_USER]->user-[r]->friend")
        .Where("user.Id = 1")
        .And()
        .Where("friend.Id = " + id)
        .And()
        .Where(string.Format("type(r) = 'FRIEND'"))                
        .Delete("r");
}

No errors, but the relationship is still there. Any ideas?

Update 11/12/2012

Got it working. I first updated by Neo4J instance with the stable 1.8. I think something with the latest neo4jclient and neo4j server were not working together. I first got the user's node based on the id, then from that node tested if the node had a relationship, then was able to remove it. Code below:

        var currentUserNode = client.Cypher.Start("root", client.RootNode)
            .Match("root-[:HAS_USER]->user")
            .Where((UserNode user) => user.Id == 1)
            .Return<Node<UserNode>>("user")
            .Results.Single();

        if (currentUserNode.StartCypher("user")
                .Match("user-[r]->friend")
                .Where("friend.Id = " + id).And()
                .Where("type(r) = 'FRIEND'")
            .Return<Node<UserNode>>("user")
            .Results
            .Count() == 1)
        {

            currentUserNode.StartCypher("user")
                .Match("user-[r]->friend")
                .Where("friend.Id = " + id).And()
                .Where("type(r) = 'FRIEND'")
                .Delete("r").ExecuteWithoutResults();
        }

Solution

  • One way is to switch to use a CypherFluentQuery instead:

    new CypherFluentQuery(client)
        .Start("root", client.RootNode)
        .Match("root-[:HAS_USER]->user-[r]->friend")
        .Where("user.Val = 1").And()
        .Where("friend.Val = " + 2).And()
        .Where("type(r) = 'FRIEND'")
        .Delete("r").ExecuteWithoutResults();
    

    which will do what you want.

    I believe this all stems from a bug: https://bitbucket.org/Readify/neo4jclient/issue/40/should-be-able-to-add-cypher-delete-clause

    As to why client.Cypher.Start isn't working as it should, I'm not sure, the bug is fixed, and should be working from version 1.0.0.479 (current at time of writing is 1.0.0.496)