Search code examples
c#neo4jcypherneo4jclient

How to call a stored procedure in neo4jclient?


I'd like to call a stored procedure (see a previous question:Question with stored procedure for Neo4J as the answer However, I can't quite see a way of doing that through the fluent query interface.

Can anyone help?

My Cypher query:

MATCH(user:UserAccount)-[:HasPermission]->(permission:Permission)
WITH user, collect(permission) as permissions
CALL apoc.map.setKey( user, 'permissions', permissions ) YIELD value as UserAccount
RETURN UserAccount

My Neo4jClient code up to now:

 _graphClient
            .Cypher
            .Match("(user:UserAccount)-[:HasPermission]->(permission:Permission)")
            .With("user, collect(permission) as permissions")
            // I need to call the stored procedure here.
            .ReturnDistinct(
                (userAccount) =>
                                new
                                {
                                    UserAccount = userAccount.As<UserAccount>()
                                });

Solution

  • I'll leave the IRawGraphClient version below, but for version 1.1.0.39 (just published today) you can use Call and Yield directly:

    _graphClient.Cypher
        .Match("(user:UserAccount)-[:HasPermission]->(permission:Permission)")
        .With("user, collect(permission) as permissions")
        .Call("apoc.map.setKey(user, 'permissions', permissions)").Yield("value AS UserAccount")
        .ReturnDistinct(
            (userAccount) => new { UserAccount = userAccount.As<UserAccount>() });
    

    OLD VERSION (Avoid if you can)

    Did you try the IRawGraphClient as I suggested in the GitHub bug you raised?

    In essence you can cast the GraphClient instance you have to an IRawGraphClient instance:

    IRawGraphClient rgc = (IRawGraphClient) client;
    

    and then call with a query - it's a bit clunky, but would be like this:

    var queryText = @"MATCH(user:UserAccount)-[:HasPermission]->(permission:Permission) 
    WITH user, collect(permission) as permissions
    CALL apoc.map.setKey( user, 'permissions', permissions ) YIELD value as UserAccount
    RETURN UserAccount"
    
    var cypherQuery = new CypherQuery(queryText, null, CypherResultMode.Projection);
    var results = rgc.ExecuteGetCypherResults<UserAccount>(cypherQuery);
    

    I think that will work - I don't have a 3.0 setup to test on at the moment, so can't be 100% sure, but please try and see.

    I'll aim to get a .Call/.Yield<T> method sorted somepoint