如何使用 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' 在上面的示例中),但这似乎不可能。
我看到的唯一解决方案是:
- 在单独的查询中获取父节点:(
- 自己做映射:( :(
- 在单独的查询中获取相关 ID,并基于该 ID 进行过滤。
也许有人看到了更好的解决方案?
原因是您的 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 以获得更好的解决方法。
假设我的图形模型包含类型 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' 在上面的示例中),但这似乎不可能。
我看到的唯一解决方案是:
- 在单独的查询中获取父节点:(
- 自己做映射:( :(
- 在单独的查询中获取相关 ID,并基于该 ID 进行过滤。
也许有人看到了更好的解决方案?
原因是您的 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 以获得更好的解决方法。