我有一个查询,其结果应该根据传递的参数进行排序:
@Query("""MATCH (u:User {userId:{uid}})-[:KNOWS]-(:User)-[h:HAS_STUFF]->(s:Stuff)
WITH s, count(h) as count ORDER BY count {order}
RETURN o, count SKIP {skip} LIMIT {limit}""")
fun findFromOthersByUserIdAndSortByAmountOfStuff(
@Param("uid") userId: String,
@Param("skip") skip: Int,
@Param("limit") limit: Int,
@Param("order) order: String): List<StuffWithCountResult>
对于order
参数,我使用以下enum
及其唯一方法:
enum class SortOrder {
ASC,
DESC;
fun toNeo4JSortOrder(): String {
when(this) {
ASC -> return ""
DESC -> return "DESC"
}
}
}
似乎SDN没有正确处理{order}
参数?执行时,我得到一个异常,告诉
Caused by: org.neo4j.kernel.impl.query.QueryExecutionKernelException: Invalid input 'R': expected whitespace, comment or a relationship pattern (line 3, column 5 (offset: 244))
" RETURN o, count SKIP {skip} LIMIT {limit}"
^
如果我从Cypher语句中删除该参数或将其替换为硬编码DESC
,则该方法成功。我相信这不是因为enum
,因为我在其他存储库方法中使用(其他)枚举,并且所有这些方法都成功了。我已经尝试了一个不同的参数命名,如sortOrder
,但这没有帮助。
我在这里缺少什么?
答案 0 :(得分:3)
这是更改排序和分页信息的错误模型。您可以跳到下面的答案来使用这些选项,或继续阅读以解释代码中的错误。
您无法将参数绑定到未为&#34;参数绑定&#34;设置的查询的语法元素中。参数绑定不会进行简单的字符串替换(因为您将对注入攻击开放),而是使用绑定API来绑定参数。您正在处理查询注释,就像它正在执行字符串替换,而这不是正在发生的事情。
parameter binding docs for Neo4J和Java manual for Query Parameters显示您可以绑定的确切位置,允许的唯一位置是:
在ORDER BY子句中没有任何内容可以说明您正在尝试的内容。
并不是说Spring Data的作者无法解决这个问题,并且允许在其他地方进行绑定,但是看起来他们做得比Neo4J Java API允许的更多。
(允许将其标记为版本4.2.0.M1
的修复程序,截至2016年9月8日为预发布版,请参阅下文,了解使用里程碑版本)
Spring Data有一个Sort
class,如果你的@Query
带注释的方法有这种类型的参数,它应该应用排序并允许它动态修改查询。
我认为代码看起来像(未经测试):
@Query("MATCH (movie:Movie {title={0}})<-[:ACTS_IN]-(actor) RETURN actor")
List<Actor> getActorsThatActInMovieFromTitle(String movieTitle, Sort sort);
(允许将其标记为版本4.2.0.M1
的修复程序,截至2016年9月8日为预发布版,请参阅下文,了解使用里程碑版本)
在当前的Spring Data + Neo4j docs中,您会看到使用分页的示例:
@Query("MATCH (movie:Movie {title={0}})<-[:ACTS_IN]-(actor) RETURN actor")
Page<Actor> getActorsThatActInMovieFromTitle(String movieTitle, PageRequest page);
(来自Spring Data + Neo4j文档中Cypher Examples的示例)
此PageRequest
class也允许排序参数化。任何实现Pageable
的东西都会这样做。使用Pageable
可能更合适:
@Query("MATCH (movie:Movie {title={0}})<-[:ACTS_IN]-(actor) RETURN actor")
Page<Actor> getActorsThatActInMovieFromTitle(String movieTitle, Pageable page);
作为替代方案,您可以查看using SpEL expressions以在查询的其他区域中进行替换。我不熟悉它,但它说:
由于此机制也公开了
Sort
或Pageable
等特殊参数类型,因此我们现在可以在本机查询中使用分页。
但official docs似乎表示它更有限。
以下是有人在GitHub issue报告您完全相同的问题。然后会导致DATAGRAPH-653问题,该问题在版本4.2.0.M1
中标记为已修复。这引用了过时的其他SO问题,因此您应该忽略那些不再正确的Paging and sorting in Spring Data Neo4j 4。
您可以在项目页面上查看dependencies information for any release。对于4.2.0.M1
构建,Gradle(您可以推断Maven)的信息是:
dependencies {
compile 'org.springframework.data:spring-data-neo4j:4.2.0.M1'
}
repositories {
maven {
url 'https://repo.spring.io/libs-milestone'
}
}
应该使用任何较新的最终版本。