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

How to filter relevant objects with Neo4j OGM typed query?

假设我的图形模型包含类型 A 的节点,这些节点与其他相同类型的节点有 parent/child 关系。

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

    // other relations to different types
    ...

}

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

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

密码语句类似于

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' 在上面的示例中),但这似乎不可能。

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

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

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

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

您也可以手动从结果列中收集结果,前提是您return 所有关系和相关节点都将被正确映射:

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

除了你列出的,你还可以

  • 为 parent
  • 提供不同的 type/label
  • 在您的会话中加载 parent 并且 return 仅节点和关系,而不是整个路径 - 类似于 RETURN node,parentRel 而不是

您可能需要在此处填写问题 https://github.com/neo4j/neo4j-ogm/issues 以获得更好的解决方法。