LDB
LDB

Reputation: 692

Neo4j.rb - Can't use order by

I have 3983 nodes of BISAC type. I cannot retrieve them using order by. Here is what is working:

irb(main):024:0* bc = Bisac.all
=> <QueryProxy  CYPHER: "MATCH (n:`Bisac`)">
irb(main):025:0> bc.count
 CYPHER 796ms MATCH (n:`Bisac`) RETURN count(n) AS n 
=> 3983
irb(main):026:0> bc.first
 CYPHER 129ms MATCH (n:`Bisac`) RETURN n ORDER BY n.uuid LIMIT {limit_1} | {:limit_1=>1}
=> #<Bisac uuid: "d1c60f13-3c70-11e5-8eb8-22000b18b199", bisac_code: "MUS037050", bisac_value: "MUSIC / Printed Music / Mixed Collections">
irb(main):027:0> bc.last
 CYPHER 127ms MATCH (n:`Bisac`) RETURN n ORDER BY n.uuid LIMIT {limit_1} | {:limit_1=>1}
=> #<Bisac uuid: "d1c60f13-3c70-11e5-8eb8-22000b18b199", bisac_code: "MUS037050", bisac_value: "MUSIC / Printed Music / Mixed Collections">

When trying to use order it fails like this:

irb(main):033:0* bc = Bisac.order('bisac_code')
=> <QueryProxy  CYPHER: "MATCH (result_bisac:`Bisac`) ORDER BY bisac_code">
irb(main):034:0> bc.count
 CYPHER 790ms MATCH (result_bisac:`Bisac`) RETURN count(result_bisac) AS result_bisac 
=> 3983
irb(main):035:0> bc.first
 CYPHER 364ms MATCH (result_bisac:`Bisac`) WITH result_bisac ORDER BY bisac_code RETURN HEAD(COLLECT(result_bisac)) as result_bisac 
Neo4j::Session::CypherError: bisac_code not defined (line 1, column 57 (offset: 56))
"MATCH (result_bisac:`Bisac`) WITH result_bisac ORDER BY bisac_code RETURN HEAD(COLLECT(result_bisac)) as result_bisac"
                                                         ^
    from /Users/levi/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/neo4j-core-5.0.10/lib/neo4j-server/cypher_response.rb:211:in `raise_cypher_error'

What is wrong here?

My gems are: neo4j (5.0.14) neo4j-core (5.0.10)

Upvotes: 1

Views: 137

Answers (1)

Brian Underwood
Brian Underwood

Reputation: 10856

Yay, things that I can actually explain right off the bat! ;)

So the reason that the ORDER BY isn't there in the count is because it would just slow down your count and it would never return a different result.

As for the .order, the reason is because you're passing in a String rather than a Symbol. Because Cypher is a more dynamic query language than SQL, I made a decision at one point to treat strings and symbols different. The idea is that if you specify a string you're probably wanted to specify a more dynamic ORDER BY clause, whereas often you'll use a Symbol to specify the property that you want to sort by. This is actually implemented in the Query API from neo4j-core, but it affects ActiveNode in the neo4j gem.

So the answer is:

bc = Bisac.order(:bisac_code)

bc.first

That said, this should really be documented and possible made smarter. I'll create an issue, thanks!

Upvotes: 1

Related Questions