我试图写一个返回相当大量数据的查询(200个节点)。节点非常简单:
public class MyPojo{
private String type;
private String value;
private Long createdDate;
...
}
我最初使用Spring Data Neo4j模板接口,但发现在返回大约100个节点后它非常慢。
public interface MyPojoRepository extends GraphRepository<MyPojo> {
public List<MyPojo> findByType(String type);
}
我打开调试,看看它为什么这么慢,结果发现SDN正在查询每个节点的标签。这是有道理的,因为我理解SDN它需要标签来进行鸭子打字。但是,Cypher一次性返回所有相关数据,因此不需要这样做。
所以,我尝试将其重写为Cypher查询:
public interface MyPojoRepository extends GraphRepository<MyPojo> {
@Query("MATCH(n:MyPojo) WHERE n.type = {0} RETURN n")
public List<MyPojo> findByType(String type);
}
这也有同样的问题。我深入挖掘了一下,虽然这个查询一次性返回了所有节点数据,但它遗漏了标签。有一种方法可以让它们在Neo4j控制台中运行,所以我尝试使用SDN:
"MATCH(n:MyPojo) WHERE n.type = {0} RETURN n, labels(n)"
不幸的是,这引起了有关多列的例外情况。查看源代码后,这是有道理的,因为Neo4j返回一个返回列的映射,在我的例子中看起来像n, labels(n)
。 SDN无法知道有一个标签列可供阅读。
所以,我的问题是:有没有办法在Cypher查询中提供标签,以防止需要再次查询每个节点?或者,除此之外,有没有办法向SDN提供包含标签和属性的Node
并将其转换为POJO?
注意:我意识到SDN团队正在努力在未来版本中完全使用Cypher。截至目前,许多代码库使用旧的(我相信,已弃用)REST服务。如果有任何未来的工作会影响到这一点,我会喜出望外来了解它。
答案 0 :(得分:3)
你是对的,它可以解决简单的用例,也应该解决。
不幸的是,当前的API不会将标签作为节点的一部分返回,因此我们必须重写内部工作以生成额外的元信息并正确返回所有这些。
一个想法是使用RETURN {id:id(n), labels:labels(n), data:n)} as n
进行完整表示。
问题是这打破了用户定义的查询。
不确定我们何时以及如何安排该工作。随意将其作为JIRA问题提出或观察/提出任何相关问题。