然后命令使用neo4j-will_paginate进行分页

时间:2014-10-31 12:46:20

标签: ruby-on-rails neo4j will-paginate

我正在尝试使用我的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')

哪个不会出错,但结果没有排序。

我非常感谢能得到的任何帮助!提前谢谢!

1 个答案:

答案 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的一部分调用的子句可以在那里调用。我们在那里执行订单而不是在最后,然后我们让它的其余部分按照通常的方式进行。

这是一个好主意但这里的问题是QueryProxyNeo4j::Core::Query类的抽象,并且没有with方法。我们用where('true = true...废话来解决这个问题。我们实际上是对服务器使用Cypher Injection攻击。哎哟。

我想我可以通过修补gem来使用with ...

来解决这个问题

此时,我确切地意识到它将如何工作,停止打字并修补宝石。结束。我在https://github.com/neo4jrb/neo4j/issues/540创建了一个问题,如果您遇到任何问题,请随时发表评论。