Search code examples
c#neo4jneo4jclient

Ordering By Relationship Property Using Neo4jClient C#


I want to get the following query in its C# equivalent:

match(p:Person)-[r1:HAS]->(s:Shelf) 
optional match(s)-[r2:CONTAINS]->(l:Link) return p,s,l 
order by r2.time_modified;

I initially thought about this but it doesn't work:

var result = await this._graphClient.Cypher
                 .Match("(person:Person { person_id: {personId}})-[r1:HAS]->(shelf:Shelf)")
                 .OptionalMatch("(shelf)-[r2:CONTAINS]->(link:Link)")
                 .WithParams(new { personId = personId })
                 .Return((shelf, link) => new 
                  {
                     Shelf = shelf.As<Shelf>(),
                     Links = link.CollectAs<Link>()
                  })
                 .OrderBy("r2.time_modified")
                 .ResultsAsync;

I get the following exception that r2 isn't defined

r2 not defined ... "ORDER BY r2.time_modified"

I am relatively new to using the Neo4jClient C# driver. Can anyone please help me and explain to me what's happening? I also want to know how to pull this off.

This is the stack trace:

at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) at System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification) at System.Threading.Tasks.Task1.get_Result() at Neo4jClient.GraphClient.<>c__851.<PrepareCypherRequest>b__85_1(Task1 response) in D:\temp\d298ce3\Neo4jClient\GraphClient.cs:line 961 at System.Threading.Tasks.ContinuationResultTaskFromResultTask2.InnerInvoke() at System.Threading.Tasks.Task.Execute() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at Neo4jClient.GraphClient.d__871.MoveNext() in D:\temp\d298ce3\Neo4jClient\GraphClient.cs:line 1022 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at ....Repository.Neo4jRepository.d__23.MoveNext() in C:\Users\Williams\documents\visual studio 2015\Projects...\Repository\Neo4jRepository.cs:line 358


Solution

  • Because you do the Collect in the Return statment, r2 doesn't exist anymore.

    You need to order before returning:

    var query = gc.Cypher
        .Match("(p:Person { person_id: 'a'})-[r1:HAS]->(s:Shelf)")
        .OptionalMatch("(s)-[r2:CONTAINS]->(l:Link)")
        .With("p,s,l")
        .OrderBy("r2.time_modified")
        .Return((p,s,l) => new
        {
             Person = p.As<Person>(),
             Shelf = s.As<Shelf>(),
             Links = l.CollectAs<Link>()
        });
    var res = query.Results;