Neo4j - 建立关系的 Cypher 语句花了将近半天的时间才完成,但出现错误 "Self-suppression not permitted"
Neo4j - Cypher statement to build relationships took near half of day to complete with error "Self-suppression not permitted"
通常我在从 CSV 文件加载时建立节点之间的关系。这是我这次用来建立节点之间关系的语句。 Language节点为39K,Description节点为2M。
MATCH (d:Description),(l:Language)
> WHERE d.description_language = l.language_name
> CREATE (d)-[r:HAS_LANGUAGE]->(l);
过了很久,运行我得到的错误是:
Self-suppression not permitted
我已经为要在关系中使用的属性创建了索引。
Indexes
...
ON :Description(woka_id) ONLINE
ON :Description(description_language) ONLINE
ON :Language(language_id) ONLINE (for uniqueness constraint)
ON :Language(language_name) ONLINE (for uniqueness constraint)
...
我在这里做错了什么导致这么长时间才能完成关系创建(超过 10 小时)?
由于您是从每个描述节点创建关系,并且有 2M 个节点,所以我只抓取尚未匹配的描述并分批进行。
类似...
match (d:Description)
where not ( d-[:HAS_LANGUAGE]->() )
with d
limit 200000
match (l:Language {language_name: d.description_language} )
create d-[:HAS_LANGUAGE]->l
您在过滤步骤处理一个非常大的笛卡尔积:
WHERE d.description_language = l.language_name
您可以尝试 MATCH
Descriptions
,按它们的 description_language
和 CREATE
将它们分组:
MATCH (d:Description)
WITH d.description_language AS dl, collect(d) as all_d_for_lang
MATCH (l:Language {language_name: dl})
UNWIND all_d_for_lang AS d
CREATE (l)-[:HAS_LANGUAGE]->(d)
如果您查看此查询的 PROFILE
,您会发现数据库命中率较低(限制第一个 MATCH
中的描述数量以进行测试)。
一般来说,我认为最好的方法是在创建节点时使用 CSV 文件生成关系,即在应用程序端而不是在数据库端。
通常我在从 CSV 文件加载时建立节点之间的关系。这是我这次用来建立节点之间关系的语句。 Language节点为39K,Description节点为2M。
MATCH (d:Description),(l:Language)
> WHERE d.description_language = l.language_name
> CREATE (d)-[r:HAS_LANGUAGE]->(l);
过了很久,运行我得到的错误是:
Self-suppression not permitted
我已经为要在关系中使用的属性创建了索引。
Indexes
...
ON :Description(woka_id) ONLINE
ON :Description(description_language) ONLINE
ON :Language(language_id) ONLINE (for uniqueness constraint)
ON :Language(language_name) ONLINE (for uniqueness constraint)
...
我在这里做错了什么导致这么长时间才能完成关系创建(超过 10 小时)?
由于您是从每个描述节点创建关系,并且有 2M 个节点,所以我只抓取尚未匹配的描述并分批进行。
类似...
match (d:Description)
where not ( d-[:HAS_LANGUAGE]->() )
with d
limit 200000
match (l:Language {language_name: d.description_language} )
create d-[:HAS_LANGUAGE]->l
您在过滤步骤处理一个非常大的笛卡尔积:
WHERE d.description_language = l.language_name
您可以尝试 MATCH
Descriptions
,按它们的 description_language
和 CREATE
将它们分组:
MATCH (d:Description)
WITH d.description_language AS dl, collect(d) as all_d_for_lang
MATCH (l:Language {language_name: dl})
UNWIND all_d_for_lang AS d
CREATE (l)-[:HAS_LANGUAGE]->(d)
如果您查看此查询的 PROFILE
,您会发现数据库命中率较低(限制第一个 MATCH
中的描述数量以进行测试)。
一般来说,我认为最好的方法是在创建节点时使用 CSV 文件生成关系,即在应用程序端而不是在数据库端。