【问题标题】:Paging and sorting in Spring Data Neo4j 4Spring Data Neo4j 4 中的分页和排序
【发布时间】:2015-08-17 22:03:46
【问题描述】:

SDN4 中的自定义查询是否支持分页?

  • 如果是,它是如何工作的?
  • 如果没有,是否有解决方法?

我有以下 Spring Data Neo4j 4 存储库:

@Repository
public interface TopicRepository 
  extends GraphRepository<Topic>,IAuthorityLookup {

  // other methods omitted
  @Query("MATCH (t:Topic)-[:HAS_OFFICER]->(u:User) "
    + "WHERE t.id = {0} "
    + "RETURN  u")
  public Page<User> topicOfficers(Long topicId, Pageable pageable);
}

以及对应的测试用例:

@Test
public void itShouldReturnAllOfficersAsAPage() {
  Pageable pageable = new PageRequest(1,10);
  Page<User> officers = topicRepository.topicOfficers(1L, pageable);
  assertNotNull(officers);
}

当我运行测试时,我遇到了以下异常

Failed to convert from type java.util.ArrayList<?> to type   org.springframework.data.domain.Page<?> for value '[org.lecture.model.User@1]'; 
nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.util.ArrayList<?> to type org.springframework.data.domain.Page<?>

这是我的设置:

dependencies {
//other dependencies omitted
  compile("org.neo4j:neo4j-cypher-dsl:2.0.1")


  compile "org.neo4j.app:neo4j-server:2.2.2"

  compile(group: 'org.springframework.data',
          name: 'spring-data-neo4j',
          version: '4.0.0.BUILD-SNAPSHOT')


  compile(group: 'org.springframework.data',
          name: 'spring-data-neo4j',
          version: '4.0.0.BUILD-SNAPSHOT',
          classifier: 'tests')

  testCompile(group: 'org.neo4j',
          name: 'neo4j-kernel',
          version: '2.2.2',
          classifier: 'tests')

  testCompile(group: 'org.neo4j.app',
              name: 'neo4j-server',
              version: '2.2.2',
              classifier: 'tests')

  testCompile(group: 'org.neo4j',
              name: 'neo4j-io',
              version: '2.2.2',
              classifier: 'tests')
} 

我使用的快照应该能够处理分页,因为以下测试运行良好:

@Test
public void itShouldReturnAllTopicsAsAPage() {

  Pageable pageable = new PageRequest(1,10);
  Page<Topic> topics = topicRepository.findAll(pageable);

  assertNotNull(topics);
}

【问题讨论】:

    标签: java spring neo4j spring-data-neo4j-4


    【解决方案1】:

    目前这是不可能的。

    要启用此功能,我们需要做一些事情。首先在启动时,我们需要检查查询的关联方法签名并将查询标记为需要分页。然后在运行时调用该方法时,我们需要获取可分页实例,提取页面参数并将它们作为 SKIP 和 LIMIT 子句应用于关联的 Cypher 查询。最后,在返回时,我们需要将结果包装在 Page 对象中。因此,要实现这一点,还需要做一些工作。

    与此同时,您可以尝试将带有参数化值的 SKIP 和 LIMIT 子句添加到查询中,并将适当的值通过 via 传递给查询方法。我还没有尝试过,但它应该可以工作 - 理论上:

      @Query("MATCH (t:Topic)-[:HAS_OFFICER]->(u:User) "
    + "WHERE t.id = {0} "
    + "RETURN  u SKIP {1} LIMIT {2}" )
    public List<User> topicOfficers(long topicId, long skip, long limit)
    

    【讨论】:

    • 感谢您的回复!我有一个问题,因为您在 SDN4 上比我有更多的洞察力......这是一项(如果有的话)将在可预见的未来可用的功能吗?比方说,SDN4的RC。这些信息对我决定是否重写我的 api 有很大帮助。
    • 它不会在第一个 RC 中可用,因为它现在处于代码冻结状态。我为它创建了一张票,并将其添加到下一个版本的待办事项中。目前我不能说那会是什么时候。 jira.spring.io/browse/DATAGRAPH-653
    • @Vince 对于我们的系统,我们需要通过执行自定义分页查询返回的 Page 的 getTotalPages()、isFirst() 和 isLast() 值。您能否提供有关如何执行此操作的任何建议/是否有 SDN 代码您可以指出我是否可以构建 Page 对象?谢谢
    • 请在此处查看我的答案:stackoverflow.com/questions/32011358/…
    • 我刚刚通过将 countQuery 添加到 @Query 注释解决了这个问题。示例:@Query(value = "MATCH (t:Topic)-[:HAS_OFFICER]->(u:User) WHERE t.id = {0} RETURN u", countQuery = "MATCH (t:Topic)-[: HAS_OFFICER]->(u:User) WHERE t.id = {0} RETURN count(u)")
    【解决方案2】:

    现在允许在查询中使用Sort 或Pageable 接口,并在DATAGRAPH-653 中修复并在版本4.2.0.M1 中标记为已修复(当前处于预发布版本)。

    可以进行如下查询:

    @Query("MATCH (movie:Movie {title={0}})<-[:ACTS_IN]-(actor) RETURN actor")
    List<Actor> getActorsThatActInMovieFromTitle(String movieTitle, Sort sort);
    

    和:

    @Query("MATCH (movie:Movie {title={0}})<-[:ACTS_IN]-(actor) RETURN actor")
    Page<Actor> getActorsThatActInMovieFromTitle(String movieTitle, PageRequest page);
    

    (来自 Spring Data + Neo4j 文档中 Cypher Examples 的示例)

    查找 Spring Data Neo4j 预发布里程碑构建:

    您可以在项目页面查看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'
        }
    }
    

    应使用任何较新的最终版本。

    【讨论】:

      【解决方案3】:

      作为@Jayson Minard 回答的后续,Spring Data Neo4j (6.0.7+) 的更新版本需要一个计数查询与常规查询一起返回一个Page 对象,例如:

      @Query(value = "MATCH (t:Topic)-[:HAS_OFFICER]->(u:User) WHERE t.id = {0} "
                   + "RETURN u SKIP $skip LIMIT $limit",
              countQuery = "MATCH (t:Topic)-[:HAS_OFFICER]->(u:User) WHERE t.id = {0} "
                   + "RETURN count(u)")
      public Page<User> topicOfficers(Long topicId, Pageable pageable);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多