2

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

Williams Adu
  • 149
  • 1
  • 12

2 Answers2

2

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;
Charlotte Skardon
  • 6,220
  • 2
  • 31
  • 42
  • What is the purpose of 'with' please? Why doesn't it contain 'r1' and 'r2'? – Williams Adu Mar 30 '16 at 13:46
  • This is one of the best i've seen regarding this question. Thanks for your input Chris. – Willie Mar 30 '16 at 14:24
  • Think of `With` as a kind of 'combiner' of queries, it's used quite often when you want to combine lots of queries together. Kind of like a `Return` in the middle of your query - where you can then use that `Return` in the next query and so on and so on - here's the docs on it: http://neo4j.com/docs/stable/query-with.html – Charlotte Skardon Mar 30 '16 at 14:49
1

You need to RETURN r2.time_modified before you can order results by it.

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

If it is returned you can use it for ORDER BY.

[EDIT]

Untested:

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, r2) => new 
                  {
                     Shelf = shelf.As<Shelf>(),
                     Links = link.CollectAs<Link>()
                  })
                 .OrderBy("r2.time_modified")
                 .ResultsAsync;
erdelmaero
  • 43
  • 8
  • I get it so how do i get it's C# equivalent? Can you add it to your answer for my examination? – Williams Adu Mar 30 '16 at 10:20
  • I just tested it but i had an exception. The truth is that i haven't created that property on all the relationships. That's why i use "Optional Match". I still get the same exception that "r2" is not defined. Is there a way to order just in case its available and ignore if it isn't there? – Williams Adu Mar 30 '16 at 10:30
  • It should work even if some of the propertys are NULL. Maybe you check this post: http://stackoverflow.com/questions/16558103/incorrect-sort-order-with-neo4jclient-cypher-query – erdelmaero Mar 30 '16 at 10:39