0

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();
        }
rball
  • 6,925
  • 7
  • 49
  • 77

2 Answers2

0

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)

Charlotte Skardon
  • 6,220
  • 2
  • 31
  • 42
  • I have the latest build 496. Tried just adding on a ExecuteWithoutResults to my existing code and also with your CypherFluentQuery and am getting this: Received an unexpected HTTP status when executing the request. The query was: START root=node({p0}) MATCH root-[:HAS_USER]->user-[r]->friend WHERE (user.Id = 1) AND (friend.Id = 2) AND (type(r) = 'FRIEND') DELETE r The response status was: 400 Bad Request The raw response body was: { "message" : "expected return clause\n\"DELETE r\"\n ^", "exception" : "expected return clause\n\"DELETE r\"\n ^", – rball Nov 12 '12 at 18:14
  • I was running 1.6.1, updated to 1.9.M01 now getting: "message":"key not found: user". – rball Nov 12 '12 at 18:38
  • OK, I'm on 1.8, 1.9 is a non-production version, when I switch to a 1.9.M01 db, I too get the error. As far as I know - neo4jclient supports up to 1.8 at present... It's not a great answer, but I think going with 1.8 is going to give you the best shot... – Charlotte Skardon Nov 13 '12 at 13:12
  • I got the error at the console, so it looks like neo4j is changing a bit or something? I was able to put where's on the ends but not the "user" part of the match. I'll go back to 1.8. – rball Nov 13 '12 at 21:53
  • try to put the "cypher 1.8" prefix to the command and run it again in the console. i too have to do that many times to actually force cypher to use the version 1.8 which supports many of the syntax features – ulkas Nov 14 '12 at 09:39
  • You'd think they would have this working already, I wonder why in later versions it seems so broken. If anything, these projects sure are changing a ton. :P – rball Nov 16 '12 at 17:46
  • Release 1.9 was released primarily to look at the the High Availability stuff they are working on, problems with Cypher etc might be in there until it's RTM'd, For consistency sake - I would only work on 1.8 for now. – Charlotte Skardon Nov 20 '12 at 09:24
  • Please don't instantiate `CypherFluentQuery` directly. Just call `client.Cypher`. – Tatham Oddie Mar 22 '13 at 04:51
0
  1. Use any Neo4jClient build after 1.0.0.500. See issue 45 if you're interested in why.
  2. Don't forget to call ExecuteWithoutResults. The first code sample in your question is missing this. This is documented on https://bitbucket.org/Readify/neo4jclient/wiki/cypher
Tatham Oddie
  • 4,290
  • 19
  • 31