java - Neo4j 图回溯算法

标签 java neo4j cypher graph-traversal

我有一个关于 Neo4j 以及 Traversal 可以做什么的复杂问题。

假设您有以下 Neo4j 图

Graph

我的想法是遍历整个图,如果我找到一个'false'节点,将这个状态扩展到他的邻居等等,最后在这个例子中我们将拥有所有状态为'false'的节点。 (在现实生活中,我有更多的条件在遍历时将这个状态设置为真或假,但我为了问题简化了一点)

我认为我需要一些回溯算法来执行此操作,但在 Neo4j 中我不知道如何执行此操作,或者是否可能。另外,这个图可能是一个非常大的图。

你会如何使用 Java 和 Neo4j 做到这一点?

谢谢。

最佳答案

为了有效匹配可达节点,有两种方法效果较好。

在 Neo4j 3.2.x 中,有一种有效的方法可以通过可变关系匹配加上 DISTINCT 的使用来匹配所有不同的可达节点,但它需要可变长度关系的上限。使用适当高的数字应该有效。像这样的东西:

MATCH (:SomeLabel{someProperty:false})-[*..999999]->(x)
WITH distinct x
SET x.someProperty = false

否则,APOC Procedures报价apoc.path.subgraphNodes()它还对子图中的可达节点进行有效匹配:

MATCH (start:SomeLabel{someProperty:false})
CALL apoc.path.subgraphNodes(start, {}) YIELD node
SET node.someProperty = false;

编辑

要为第一个选项添加更多详细信息(为什么不只使用 *,以及为什么使用 DISTINCT),请记住,默认情况下,当我们使用 时,Cypher 将匹配所有可能的路径*,即使这些路径结束于与先前匹配的路径相同的节点。这在充分连接的图中可能会变得低效(当我们没有合理的上限,并且我们没有使用 LIMIT 时),并且有可能导致堆崩溃或无限期挂起。

当我们对所有可能的路径不感兴趣,只对所有可到达的可能节点感兴趣时,尤其要避免这种情况。

在 Neo4j 3.2 中,引入了一种称为 pruning-var expand 的优化,它会在以下所有情况下更改遍历逻辑:

  1. 我们有一个变长扩展
  2. 我们不以任何方式引用路径(例如通过将路径变量设置为匹配模式,或在 var-length 关系上设置变量)
  3. 我们有一个 var-length 扩展的上限
  4. 我们要求从扩展中获得 DISTINCT 节点或值

基本上当查询是这样的时,很明显我们想要来自 var-length 扩展的不同节点(或来自不同节点的值)并且不关心路径。

然后规划器将使用修剪变量 expand(您可以通过检查来自 EXPLAIN 或 PROFILE 的查询计划来确认)来有效地匹配可达节点。

关于java - Neo4j 图回溯算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47183688/

相关文章:

java - 通过java检索neo4j节点数据时出错

neo4j - 对路径上的所有节点执行 MATCH

java - Play Ebean 列表 null

java - 使用 Java 发送 HTTP Post Payload

java - Spring 4 动态 Bean 创建

neo4j - 实现类型继承的 Cypher 查询

neo4j - 查询在没有克隆过程的情况下复制具有 Neo4j 关系的节点

merge - neo4j cypher更新现有节点或创建新节点

Neo4j 密码查询以组合结果

java - Web应用程序无法获取资源