我正在使用 AWS Neptune 并使用 python 和 neo4j 来查询数据库。 我很难通过节点 ID 获取完整的层次结构。
我想要直接和间接连接到特定节点的所有子节点和子子节点。 节点属性: (
~id
, '实体名称', '实体类型', ~label
)
边缘属性:
(~id
, ~label
, 'journey_id')
我尝试了多个查询,但由于我的 aws neptune 超时为 10 分钟,所以 10 分钟后超时。
MATCH (source)<-[relationship*]-(target)
WHERE source.`~id` = '{entity_id}'
RETURN source, relationship, target
MATCH (source)<-[relationship*]-(target)
WHERE source.`~id` = '{entity_id}'
RETURN COLLECT(DISTINCT target)
MATCH (source)<-[relationship*]-(target)
WHERE source.`~id` = '{entity_id}'
RETURN COLLECT(DISTINCT [ID(startNode(relationship)), TYPE(relationship), ID(endNode(relationship))])
MATCH p=(source)<-[relationship*]-(target)
WHERE source.`~id` = '{entity_id}'
WITH p, source, target, nodes(p) AS n, relationships(p) AS r
UNWIND n AS node
WITH source, target, COLLECT(DISTINCT node) AS NODES, r
UNWIND r AS rel
WITH source, target, nodes, COLLECT(DISTINCT rel) as rels
RETURN source, target, nodes, rels
MATCH (source)<-[relationship*]-(target)
WHERE source.`~id` = '{entity_id}'
AND EXISTS( (source)<-[]-() )
RETURN source
MATCH p=(source {`~id`: '{entity_id}'})-[relationship*]-(target)
WITH DISTINCT p as path, source, target
return source, relationships(path) as rels, target
我已经厌倦了上述所有查询,但效率不够。如果我将层次结构限制在某个级别,它就可以正常工作,但在我的场景中,我想要完整的层次结构。
有人可以帮忙吗?
在讨论 Neptune 数据库的以下内容之前,我还应该提到,如果这些模式是您的主要用例(基本上是弱连接组件算法),那么您可能需要考虑使用 Neptune Analytics 而不是 Neptune 数据库。 Neptune Analytics 具有用于执行图形算法的内置功能:https://docs.aws.amazon.com/neptune-analytics/latest/userguide/wcc.html
注意:Neptune Analytics 是一个单独的数据存储。 您需要创建 Neptune Analytics Graph 并获取数据来执行这些算法。
如果您还没有升级到引擎版本
1.3.2.1
,因为此版本中 openCypher 查询性能有了显着增强。
这里一个可能的问题是使用传入的边缘遍历而不提供边缘标签。 下面介绍 Neptune 的索引方案 [1] 以及当您通过没有标签的传入边进行查询时会发生什么。
边缘标签存储在索引中的 P 位置。 有 POGS 索引,但不知道边类型需要在 POGS 索引中查找所有作为边标签的 P。 如果可以指定要遍历的边标签,这样可以使查询更加高效。
您可以提供可能的边缘标签,例如:
MATCH (source)<-[relationship:LABEL1:LABEL2:LABEL3*]-(target)
WHERE source.`~id` = '{entity_id}'
RETURN source, relationship, target
我还要指出,如果这是常见模式,您可能需要切换边缘的方向。 在所有条件相同的情况下,沿任一方向穿过边缘的性能应该相似。 但是,Neptune 在 SPOG 索引中存储与原始顶点信息相邻的传出边:
<S> <P> <O> <G>
<vertex_id> <~type> <label> <~>
<vertex_id> <propertykey> <value> <~>
<vertex_id> <edge_label> <vertex_id> <edge_id>
因此,顶点 ID、属性和出边更有可能保存在同一组数据库页面中。 这意味着通过 ID 查找顶点可能还会获取该顶点的传出边缘信息并将其缓存在缓冲池缓存中。 这使得传出边缘遍历的效率稍微提高(更少的存储访问 - 更多地在内存中完成)。
当查询传入边(带有标签)时,POGS 索引将用于查找另一边的边和顶点 ID:
<P> <O> <G> <S>
<edge_label> <incoming_vertex_id> <edge_id> <outgoing_vertex_id>
但是当查询出边时,将使用SPOG索引。 由于您绑定在 S(传出顶点 id)上,因此不需要提供边标签。
[1] https://docs.aws.amazon.com/neptune/latest/userguide/feature-overview-data-model.html
除了上述内容之外,如果您可以提供 openCypher 解释计划输出,我们可以查看查询/数据的潜在其他方面,这可能有助于提高这些查询的效率:https://docs.aws.amazon.com/海王星/最新/用户指南/access-graph-opencypher-explain.html