我正在尝试使用我的rails app上的neo4j-will_paginate gem分页,但我在订购记录时遇到问题,然后对它们进行分页。
如果我尝试:
@things = Thing.all.order(title: :desc)
或
@things = Thing.all.paginate(:page => params[:page], :per_page => 20)
这些单独工作很好,但如果我尝试
@things = Thing.all.order(title: :desc).paginate(:page => params[:page], :per_page => 20)
它会产生一个"未知标识符`n`。"错误
从rails服务器,生成的Cypher查询是:
CYPHER 13ms MATCH (n:`Thing`) RETURN count(n) AS count ORDER BY n.title DESC
Completed 500 Internal Server Error in 14ms
Neo4j::Session::CypherError (Unknown identifier `n`.):
我也试过
@things = Thing.all.paginate(:page => params[:page], :per_page => 2, :order => 'title DESC')
哪个不会出错,但结果没有排序。
我非常感谢能得到的任何帮助!提前谢谢!
答案 0 :(得分:1)
我是那个人,嗯......这个问题很尴尬...... 责备。 neo4j-will_paginate
宝石很快适应了Neo4jrb 3.0,因此,我把它放到那里就是根据需要进行修补。
无论如何,这有两个原因导致失败,而且这两个原因都不是你的错。我刚修补了Neo4j和neo4j-will_paginate宝石来解决这个问题。我在您上次尝试中添加了order
选项,但您需要使用带标识符的符号,哈希或字符串。其中之一:
@things = Thing.all.paginate(:page => params[:page], :per_page => 2, :order => :title)
@things = Thing.all.paginate(:page => params[:page], :per_page => 2, :order => { title: :desc })
@things = Thing.as(:t).paginate(:page => params[:page], :per_page => 2, :order => 't.title DESC')
在我们为neo4j-will_paginate
执行新版本之前,我无法执行neo4j
的新版本,因此在此期间,请将gemfile指向每个repo或ref的主分支注意到的提交。
gem 'neo4j', github: 'neo4jrb/neo4j', branch: 'master',
gem 'neo4j-will_paginate', github: 'neo4jrb/neo4j-will_paginate', branch: 'master'
#or
gem 'neo4j', github: 'neo4jrb/neo4j', ref: 'b4ee152becb827d87a7659d1beebfb043d0560f6'
gem 'neo4j-will_paginate', github: 'neo4jrb/neo4j-will_paginate', ref: 'b85b622087f3929c37231570f4d24021dcff4ee0'
我们为Neo4j保留了一个完全通过的主分支。
在将它直接修复到gem之前,我找出了问题的原因和一个糟糕的解决方法并输入了它。我将把它包括在这里,因为它揭示了一些有关为什么会发生这种情况的信息,以及如何在它们弹出时解决Cypher DSL的局限性。最后,您在order
中对paginate
选项的建议让我了解如何正确处理它。
不必要的解决方法:
Thing.as(:t).where('true = true WITH t ORDER BY t.name desc').paginate(:page => params[:page], :per_page => 2)
在Cypher中,会产生两个问题:
MATCH (t:`Thing`) WHERE true = true WITH t ORDER BY t.name desc RETURN count(DISTINCT t) AS t
MATCH (t:`Thing`) WHERE true = true WITH t ORDER BY t.name desc RETURN t SKIP 0 LIMIT 10
请务必注意我们在开头设置as
标识符的事实。只要在where
方法中使用相同的东西,就可以设置任何你想要的东西。
所有必要的原因是will_paginate
如何计算要显示的总页数。当您致电paginate
时,您的查询已调用count
,正如您在第一个Cypher声明中看到的那样。既然已经修复了count
错误( EDIT 这包含在一个介绍部分中,我提到修复导致你的特定错误但不是整个问题的错误),那个看起来像这样:
MATCH (result:`Thing`) RETURN count(result) AS result ORDER BY result.name, result.desc
# results in error:
# Neo4j::Session::CypherError: Type mismatch: expected Map, Node or Relationship but was Integer (line 1, column 66)
查询和订单清楚地表明问题所在:您无法对整数进行排序。 WITH
救援! WITH
基本上将我们的单个查询分成两个单独的查询。通常必须作为RETURN
的一部分调用的子句可以在那里调用。我们在那里执行订单而不是在最后,然后我们让它的其余部分按照通常的方式进行。
这是一个好主意但这里的问题是QueryProxy
是Neo4j::Core::Query
类的抽象,并且没有with
方法。我们用where('true = true...
废话来解决这个问题。我们实际上是对服务器使用Cypher Injection攻击。哎哟。
我想我可以通过修补gem来使用with
...
此时,我确切地意识到它将如何工作,停止打字并修补宝石。结束。我在https://github.com/neo4jrb/neo4j/issues/540创建了一个问题,如果您遇到任何问题,请随时发表评论。