neo4jneo4jclient

Get <id> of the Neo4j node into class


My Class definition:

public class User{
    public int Id {get;set;}
    public string Name {get;set;}
}

My Cypher:

MATCH (u:User)
WHERE id(u) = 15
RETURN u{.*, id:id(u)} as user

My C#.Net code:

var users = await graphClient.Cypher.Match("(u:User)").Where("id(u)=15).Return<User>(u => u.As<User>()).ResultAsync;

When I check the result, User.Id always comes as NULL.

Note: I have not created and Id property inside node but rather I would like to use Neo4j's inbuilt Id.

see attached


Solution

  • The <id> you see in the browser is the underlying Neo4j ID, it's not a normal property of the Node that the Id property of your User class would be attempting to get.

    To get what you're after, you'll have to do a bit more with the code, in fact, pretty much what you have in your Cypher.

    var users = await graphClient.Cypher
        .Match("(u:User)")
        .Where("id(u)=15")
        .With("u{.*, Id:id(u)} AS user")
        .Return(user => user.As<User>())
        .ResultsAsync;
    

    I do the conversion into a type in a With largely as it means I can use the .* notation, and also allows me to then return the user.As<User>().

    I've also changed the case of the Id property you return from id:id(u) to Id:id(u) - as the case on your class is upper case.

    I would recommend using a parameter for the Id as well:

    var users = await graphClient.Cypher
        .Match("(u:User)")
        .Where("id(u)=$id")
        .With("u{.*, Id:id(u)} AS user")
        .WithParam("id", 15)
        .Return(user => user.As<User>())
        .ResultsAsync;
    

    As it'll make the query analyzer of Neo4j recognise this is the same query being run multiple times, and make your query faster.

    Now - On this, you really shouldn't be using the <id> as a queryable parameter except in very rare cases. The <id> can point to different things over the time of the database. For example, if you deleted this User and added another one, that new one might reuse the <id>. If you can, always try to find another unique id to use, in .NET, Guid.NewGuid() is one of the classics, or of course, for a User - Email Address tends to be good.