2017-04-19 61 views
0

比方说,我的图模型包含类型为A的节点,它与同类型的其他节点具有父/子关系。如何用Neo4j OGM类型查询过滤相关对象?

@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特性,我可以指定结果列(上面的例子中的'节点')与感兴趣的节点,但这似乎不可能。

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

  • 在单独的查询:(取父节点
  • 做映射自己:(:(
  • 获取有关IDS基于一个单独的查询和过滤器上。

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

回答

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以获得更好的解决方法。

+0

Thx为您的答复。使用不同的标签是不行的,因为我们真的在谈论相同的节点类型。关于你的第二个选项,如果我只返回关系,那么我将无法浏览我的节点afaik。我会填补一个问题,因为这似乎并不是一个孤立的用例... – Christian

+0

https://github.com/neo4j/neo4j-ogm/issues/351 – Christian

+0

@Christian只记得还有另一种方式..见编辑回答 –