【问题标题】:A possible Spring Data Bug with SDN Neo4J Cypher QuerySDN Neo4J Cypher Query 可能存在的 Spring 数据错误
【发布时间】:2017-02-14 17:53:29
【问题描述】:

以下查询应返回按“关注者”数量按 desc 顺序排序的帐户,并有限制。

它需要 2 个变量作为参数(maxCount 和 limit)。 MaxCount 是指关注者的数量。因此,如果 maxCount 为 100,则仅返回关注者少于 100 的那些帐户。

如果我在 Spring Data Neo4j 应用程序中运行此查询。它似乎忽略了 maxCount 约束,例如如果我将 maxCount 设置为 2,并且 account1 有 3 个关注者,而 account2 有 1 个关注者。当它应该只返回只有 1 个关注者的 account2 时,它似乎错误地返回了两个帐户。

查询

@Query("MATCH (a:Account)<-[:follows]-(b:Account) WITH a, COLLECT(b)
AS bs WHERE SIZE(bs) < {0} RETURN a ORDER BY SIZE(bs) DESC LIMIT {1}")
List<Account> findCappedSortedAccountByFollowers(int maxCount, int resultSize);

直接输入 Neo4j 控制台就可以了

也许这是 Spring Data Bug?

SDN 版本:4.1.3.RELEASE

OGM 嵌入式驱动程序版本:2.0.5

小程序演示问题可用here

【问题讨论】:

  • 你能用 SDN 4.2.0.BUILD-SNAPSHOT 和 OGM 2.1.0-SNAPSHOT 试试吗?您可能需要这个:graphaware.com/neo4j/2016/09/30/upgrading-to-sdn-42.html 进行设置。
  • 您是否运行了示例应用程序?
  • 是的。它适用于这些版本。
  • 我刚刚更新到快照,但结果相同。查看修改后的示例应用

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


【解决方案1】:

您的代码已更新以适用于新版本。两项测试均通过。我已经重写了您的测试和模型,使其更符合我们的文档和示例。请记住,OGM 可以通过可达性持续存在。希望这可以帮助您解决问题。我在这里解释了如何使用 Spring Data 编写事务类型测试:https://stackoverflow.com/a/39887536/2271422

build.gradle

dependencies {
    compile "ch.qos.logback:logback-classic:1.1.7"
    compile "org.springframework.data:spring-data-neo4j:4.2.0.BUILD-SNAPSHOT"
    compile "org.springframework:spring-test:4.3.3.RELEASE"
    compile "org.neo4j:neo4j-ogm-embedded-driver:2.1.0-SNAPSHOT"
    testCompile "junit:junit:4.12"
}

src/main/java com.neo4j.relation.config:

@Configuration
@EnableNeo4jRepositories("com.neo4j.relation.repository")
@EnableTransactionManagement
public class EmbeddedNeo4JConfig {

    @Bean
    public SessionFactory sessionFactory() {
        return new SessionFactory("com.neo4j.relation.model");
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new Neo4jTransactionManager(sessionFactory());
    }
}

src/main/java com.neo4j.relation.model:

@NodeEntity
public class Account {

    @GraphId
    private Long id;

    private String name;

    @Relationship(type = "FOLLOWS",
            direction = Relationship.OUTGOING)
    private Set<Account> following = new HashSet<Account>();

    @Relationship(type = "FOLLOWS",
            direction = Relationship.INCOMING)
    private Set<Account> followers = new HashSet<Account>();

    private Account() {
    }

    private Account(String name) {
        this.name = name;
    }

    public static Account newAccountInstance(String name) {
        return new Account(name);
    }

    //Accessors
    public Long getId() {
        return id;
    }

    public Set<Account> getFollowers() {
        return followers;
    }

    public String getName() {
        return name;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("Id: ").append(getId()).append(", ");
        sb.append("Name: ").append(getName()).append(", ");
        return sb.toString();
    }
}

src/main/java com.neo4j.relation.repository:

public interface AccountRepository extends GraphRepository<Account> {
    @Query("MATCH (a:Account)<-[:FOLLOWS]-(b:Account) WITH a, COLLECT(b) AS bs ORDER BY SIZE(bs) DESC RETURN a LIMIT {0}")
    List<Account> findSortedAccountByFollowers(int maxSize);

    @Query("MATCH (a:Account)<-[:FOLLOWS]-(b:Account) WITH a, COLLECT(b) AS bs WHERE SIZE(bs) <= {0} RETURN a ORDER BY SIZE(bs) DESC LIMIT {1}")
    List<Account> findCappedSortedAccountByFollowers(int maxCount, int resultSize);
}

src/test/resources logback.xml:

<configuration>

    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d %5p %40.40c:%4L - %m%n</pattern>
        </encoder>
    </appender>

    <logger name="org.neo4j.ogm" level="debug" />
    <logger name="org.springframework" level="warn" />
    <logger name="org.springframework.data.neo4j" level="debug" />
    <root level="debug">
        <appender-ref ref="console" />
    </root>

</configuration>

src/test/resources com.neo4j.test:

@ContextConfiguration(classes = {EmbeddedNeo4JConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
public class AccountTester {

    @Autowired
    AccountRepository accountRepository;

    @Test
    public void testFindSortedAccountByFollowers() {

        Account account = Account.newAccountInstance("James Martin");
        Account account2 = Account.newAccountInstance("Steve Owen");
        Account account3 = Account.newAccountInstance("Bill Gates");
        Account account4 = Account.newAccountInstance("Steve Jobs");
        account.getFollowers().add(account2);

        accountRepository.save(account);
        accountRepository.save(account3);
        accountRepository.save(account4);

        assertNotNull(account.getId());

        final Iterable<Account> all = accountRepository.findAll();

        assertEquals(4, IteratorUtils.size(all.iterator()));

        List<Account> accounts = accountRepository.findSortedAccountByFollowers(10);
        int size = accounts.size();
        assertEquals(1, size);
        assertEquals(account, accounts.get(0));
    }

    @Test
    public void testCappedSortAccountByFollowerCount() {
        Account account = Account.newAccountInstance("Steve Martin");
        Account account2 = Account.newAccountInstance("Steve Owen");
        Account account3 = Account.newAccountInstance("Bill Gates");
        Account account4 = Account.newAccountInstance("Steve Jobs");

        account.getFollowers().add(account2);
        account.getFollowers().add(account3);
        account.getFollowers().add(account4);

        account4.getFollowers().add(account3);

        accountRepository.save(account);

        List<Account> accounts = accountRepository.findCappedSortedAccountByFollowers(2, 10);
        int size = accounts.size();
        assertEquals(1, size);
        assertEquals(account4, accounts.get(0));
    }
}

【讨论】:

  • 它是通过可达性添加的。测试通过。
猜你喜欢
  • 2014-12-01
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多