【问题标题】:Neo4j Cypher: Match and Delete the subgraph based on value of node propertyNeo4j Cypher:根据节点属性的值匹配和删除子图
【发布时间】:2016-12-15 22:17:08
【问题描述】:

假设我在 Neo4j 中有 3 个子图,如果子图中的所有节点都与每个节点的属性值 whole 子图。但是如果子图中有至少一个节点与条件不匹配,则不会删除子图。

在这种情况下,左子图将被删除,但右子图和中间子图将保留。 即使它有一些值为1的节点也不会被删除,因为也有值大于1的节点。

useridsvalues 是节点属性。

如果有人能向我推荐可用于执行此操作的密码查询,我将不胜感激。请注意,查询将在整个图上进行,即在所有三个子图上,如果有的话,在更多子图上。

【问题讨论】:

  • “子图”是指“断开的子图”吗?
  • 了解所有涉及的节点是否具有相同的标签,或者这些节点是否有多个标签会有所帮助。如果是,是否对 value 属性进行了索引?
  • @InverseFalcon 是节点属于标签。并且 value 属性也被索引。
  • @cybersam 是的,他们是断开连接的子图

标签: neo4j cypher graph-databases subgraph


【解决方案1】:

感谢您的澄清,这是一个棘手的要求,我还不清楚哪种方法可以很好地适应大型图,因为大多数可能性似乎都是昂贵的全图操作。我们可能需要使用几个步骤来设置图表以便稍后查询。我还假设您的意思是“断开连接的子图”,否则此答案将不起作用。

一个开始可能是根据属性值将节点标记为 :Alive 或 :Dead。如果所有节点都具有相同的标签,并且该标签的 value 属性上有索引,这应该会有所帮助,因为我们的匹配操作可以利用索引,而不必进行完整的标签扫描和属性比较。

MATCH (a:MyNode)
WHERE a.value <= 1
SET a:Dead

分别

MATCH (a:MyNode)
WHERE a.value > 1
SET a:Alive

那么您标记要删除的节点的查询将是:

MATCH (a:Dead)
WHERE NOT (a)-[*]-(:Alive)
SET a:ToDelete

如果您标记为删除的节点看起来一切正常,您可以运行删除操作,必要时使用 APOC 过程中的 apoc.periodic.commit() 批处理操作。

MATCH (a:ToDelete)
DETACH DELETE a

如果对断开连接的子图进行操作很常见,我强烈建议您使用连接到您创建的每个子图的特殊节点(例如子图头部的单个 :Cluster 节点),以便您可以在以下位置开始此类操作:集群节点,这将大大加快此类查询,因为您的查询操作将在每个集群中执行,而不是每个 :Dead 节点。

【讨论】:

  • 非常感谢。它完美地工作。在最初的用例中,我将拥有大约 7000 万个节点,并且每天我可能需要删除 4-6 百万个节点。所以我希望它能很好地扩展。 :Cluster 节点的想法非常有趣,但我不确定它是否可行,因为我每天都会有新节点出现。因此,每次添加节点时,都需要进行搜索以了解是否应添加 :Cluster 节点。
  • 添加新节点时,您是否知道它们是否会链接到现有集群,或者它们是否会启动自己的新集群?如果您知道这一点,您可以在添加新节点之前添加一个创建 :Cluster 节点的步骤。另外,你的价值观会改变吗?如果它们要保持不变,则可能值得在创建时添加任何适当的标签(:Alive 或 :Dead,尽管 :Dead 可能应该使用不同的名称)。如果它们会发生变化,您可能需要在完成删除操作后删除这些标签,以免对陈旧数据进行操作。
  • 否,添加新节点时可能不会形成新集群或形成新集群。这就是我使用merge 操作的原因。您可以将值视为时间戳,它不会改变,并且删除是基于时间戳发生的。例如,假设我要维护 10 天的图形数据,因此每天都会有新的删除和插入。每天的新节点可能与旧集群叠加,也可能自行形成新集群。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
相关资源
最近更新 更多