【问题标题】:Create relation between large amout of nodes in cypher在密码中创建大量节点之间的关系
【发布时间】:2015-03-02 08:05:58
【问题描述】:

鉴于此问题的以下图表:Cypher 2 not using schema index with OR operator

CREATE 
(:Application {Name: "Test Application", Aliases: ["Test", "App", "TestProject"]}),
(:Application {Name: "Another Application", Aliases: ["A-App", "XYZ", "XYProject"]}),
(:Application {Name: "Database X", Aliases: ["DB-App", "DB", "DB-Project"]}),
(:System {Name: "Server1", Application: "TestProject"}),
(:System {Name: "Server2", Application: "Test Application"}),
(:System {Name: "Server3", Application: "another App"}),
(:System {Name: "Server4", Application: "Some Database"}),
(:System {Name: "Server5", Application: "App"}),
(:System {Name: "Server6", Application: "App XY"}),
(:System {Name: "Server7", Application: "App DB"}),
(:System {Name: "Server8", Application: "Test"}),
(:System {Name: "Server9", Application: "TestProject"}),
(:System {Name: "Server10", Application: "test"}),
(:System {Name: "Server11", Application: "App XY"});

CREATE INDEX ON :Application(Name);
CREATE INDEX ON :Application(Aliases);

CREATE INDEX ON :System(Application);

但有 900 个Application 和 200.000 个Systemnodes。

我向其中一个应用程序添加了一个新别名(例如“Test MiniApp”)(最终将匹配生产数据库中约 27.000 个新的System 节点)并运行以下查询:

MATCH (a:Application { Name: "Test Application"})
WITH a
MATCH (s:System)
WHERE s.Application IN (a.Aliases + a.Name)
AND NOT (a)-[:InstalledOn]->(s)
CREATE UNIQUE (a)-[:InstalledOn]->(s)

此查询使用生产数据库上的架构索引(使用 PROFILE 测试),但运行时间太长,大约 5 分钟。我想知道为什么要为通过索引找到的约 27k 节点创建关系需要这么长时间。

Neo4j 2.1.6 在具有 96 GB RAM 的 Linux 系统 (SLES 11) 上以默认设置运行。

编辑 上面的查询只返回Application 类型的单个节点,并且仅在重命名应用程序和/或添加/删除别名时执行。由于这两个实体在任何时候都来自外部系统,因此我不能只使用新系统可能与应用程序直接相关的情况,因为它在导入期间可能不存在。因此,当有人向应用程序添加新别名等时,我需要找到所有匹配的系统并创建该关系。

【问题讨论】:

  • 有多少应用程序匹配 {Name: "Test Application"}?只有一个?似乎在这里您正在查看大多数 :Systems 上的大多数 :InstalledOn 关系,这可能很慢(其中 200K)。恐怕由于您正在寻找与特定节点未连接的事物,因此这固有地需要一些时间,因为显然您无法利用关系来遍历这些节点。
  • 您好,只有一个具有此名称和/或别名的应用程序节点。
  • 您可能应该根据需要创建从 :Application:System 的关系以捕获该关系 (where s.Application IN (a.Aliases + Name)) - 根据跨 200k System 节点的一长串可能性检查属性似乎即使使用索引,您也不想每次都重新计算。也许您甚至不需要:System 上的Application 属性?
  • 好吧,用例,如果应用程序被更新(例如名称更改和/或别名添加/删除),则执行查询。它不是用来搜索的。这里的问题是这两个数据随时都来自外部系统。更新一个新/更改系统的搜索,因为您只寻找 900 个应用程序,但是当应用程序更改时,我需要该查询来创建关系。
  • 我的观点是neo4j倾向于使关系遍历速度更快;匹配属性值较慢。如果您可以维护属性值列表,您还可以维护捕获相同数据的 rel 列表。我不知道你的模型,所以我不能肯定地说,但是当 rels 存在时(并且更快),尝试通过某个值加入节点群体是一种经常观察到的反模式。同样,您正在尝试在此查询中查找 连接的内容;考虑如何利用模型中的 rel 来简化您的要求。

标签: neo4j cypher


【解决方案1】:

WHERE 子句中检查NOT (a)-[:InstalledOn]->(s) 应该是不必要的,因为CREATE UNIQUE (a)-[:InstalledOn]->(s) 会自动为你做同样的检查。从本质上讲,您要进行两次相同的检查。

这会加快速度吗?

MATCH (a:Application { Name: "Test Application"}), (s:System)
WHERE s.Application IN (a.Aliases + a.Name)
CREATE UNIQUE (a)-[:InstalledOn]->(s)

【讨论】:

  • MATCH x,y WHERE ... 语法不会使用模式语法,而是使用 NodeByLabel .. 非常慢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多