根据某些属性为现有节点创建新创建节点的最近一个关系

时间:2018-02-14 21:56:06

标签: neo4j cypher

我的应用程序接收数据流,我需要在图表数据库中保留。有了这些数据,我首先在neo4j db中批量创建节点(1000),之后我试图找出现有数据中的匹配节点来链接它。

MATCH(new:EVENT) where new.uniqueId in [NEWLY CREATED NODES UNIQUE ID]
MATCH (existing:EVENT)  where new.myprop = existing.myprop and new.uniqueId <> exising.uniqueID
CREATE (new)-[:LINKED]-(existing)

我的问题是,如果一个节点有多个匹配的现有节点,那么我想与一个现有节点建立关系。我当前的上述查询将创建与所有匹配节点的关系。

是否有任何有效的方法,因为现有节点的数量可能很大,即大约300M。

节点:我在myprop和uniqueId字段上创建了索引

2 个答案:

答案 0 :(得分:1)

正如@InverseFalcon的回答所述,您可以使用aggregation为每个不同的existing收集new个节点,并在每个集合中取第一个节点。

为了获得更好的性能,您应始终PROFILE查询以查看可以改进的内容。例如,在我的neo4j安装上使用一些示例数据执行此操作之后,我看到:在查找new时未自动使用索引,并且new.uniqueId <> exising.uniqueId测试导致数据库命中。此查询修复了这两个问题,并且应该具有更好的性能:

MATCH(new:EVENT)
USING INDEX new:EVENT(uniqueId)
WHERE new.uniqueId in [NEWLY CREATED NODES UNIQUE ID]
MATCH (existing:EVENT)
WHERE new.myprop = existing.myprop AND new <> existing
WITH new, COLLECT(existing)[0] AS e
CREATE (new)-[:LINKED]->(e);

它使用USING INDEX提供使用索引的提示。此外,由于uniqueId应该是唯一的,因此它只是直接比较newexisting节点,看它们是否是同一个节点。

为了确保neo4j实际强制执行唯一性,您应该创建一个uniqueness constraint

CREATE CONSTRAINT ON (e:EVENT) ASSERT e.uniqueId IS UNIQUE;

答案 1 :(得分:0)

您可以收集每个新节点的现有节点匹配,然后抓住第一个:

MATCH(new:EVENT) where new.uniqueId in [NEWLY CREATED NODES UNIQUE ID]
MATCH (existing:EVENT)  where new.myprop = existing.myprop and new.uniqueId <> exising.uniqueID
WITH new, head(collect(existing)) as existing
CREATE (new)-[:LINKED]-(existing)