如何使用Neo4j OGM类型查询过滤相关对象?

时间:2017-04-19 08:30:42

标签: neo4j mapping cypher neo4j-ogm

假设我的图模型包含类型A的节点,这些节点与同一类型的其他节点具有父/子关系。

@NodeEntity(label = "A")
class A {
    @Relationship(type = "PARENT")
    private A parent;

    // other relations to different types
    ...

}

我正在使用以下会话方法来执行复杂查询(用于分页,过滤,可选匹配等)

session.query(A.class, cypher, parameters)

其中cypher语句类似于

MATCH (node:A) WHERE ... OPTIONAL MATCH ... RETURN node, ... ORDER BY node.id ASC LIMIT 100

现在,我还想为每个结果(也是A类型)获取父节点。为此,我用

扩展了我的查询
MATCH (node:A) WHERE ... OPTIONAL MATCH parentRels=(node)-[parentRel:PARENT*1..]->(:A) RETURN node, collect(parentRel) ORDER BY node.id ASC LIMIT 100

我天真地期待看到的是我的相同的对象列表A,其中每个父字段都很好地填充,直到根。 Neo4j返回的结果是正确的,但是OGM返回的映射结果是无用的,因为现在它不仅包含我感兴趣的节点(正确填充了父字段,是),但所有父节点也最终都在结果列表!

所以我开始寻找一个隐藏的OGM功能,我可以用感兴趣的节点指定结果列(上例中的'node'),但这似乎不可能。

我看到的唯一解决方案是:

  • 在单独的查询中获取父节点:(
  • 自己做映射:( :(
  • 在单独的查询中获取相关ID并根据该过滤进行过滤。

也许有人看到了更好的解决方案?

1 个答案:

答案 0 :(得分:0)

原因是您的父母也与您在query方法中传递的类型相匹配 - A.class

OGM无法知道您的实际需求结果是什么,因此将所有匹配的节点映射到结果 - 一行可能会导致结果列表中的2个甚至更多项。 (请注意,有些人使用相反的用例并且实际上希望这种情况发生)。

您还可以手动收集结果列中的结果,前提是您返回正确映射的所有关系及相关节点:

Result result = session.query(cypher, parameters)
for(Map<String, Object> map : result.queryResults()) {
    (A) map.get("node"); // collect result manually to some collection
}

除了你列出的内容,你也可以

  • 为父母提供不同的类型/标签
  • 让父母加载到您的会话中并仅返回节点和关系,而不是整个路径 - 例如RETURN node,parentRel而不是

您可能希望在https://github.com/neo4j/neo4j-ogm/issues填写问题,以便更好地解决此问题。