在 Neo4j 1.8 中查找重复节点的有效方法?
An effective way to lookup duplicate nodes in Neo4j 1.8?
我正在尝试以编程方式定位 Neo4j 1.8 数据库中的所有重复节点(使用 Neo4j 1.8)。
需要检查的节点都有一个(非索引)属性 externalId
,我想为其找到重复项。这是我得到的 Cypher 查询:
START n=node(*), dup=node(*) WHERE
HAS(n.externalId) AND HAS(dup.externalId) AND
n.externalId=dup.externalId AND
ID(n) < ID(dup)
RETURN dup
数据中的节点数少于 10K,带有 externalId
的节点数少于 1K。
上面的查询正在运行,但似乎表现不佳。有没有内存消耗更少的方法来做到这一点?
试试这个查询:
START n=node(*)
WHERE HAS(n.externalId)
WITH n.externalId AS extId, COLLECT(n) AS cn
WHERE LENGTH(cn) > 1
RETURN extId, cn;
它避免了节点的笛卡尔积。它找到不同的 externalId
值,收集具有相同 id 的所有节点,然后过滤掉不重复的 id。结果中的每一行都将包含一个 externalId 和具有该 ID 的重复节点的集合。
start 子句包括全图扫描,然后组装整个节点集的笛卡尔积(从 10k * 10k = 100m 对开始),然后根据中的标准缩小这个非常大的列表where 子句。 (也许这里有密码优化?我不确定)
我认为在 externalId 上添加索引将是一个明显的胜利,并且目前可能会提供足够的性能提升,但您也可以考虑以不同的方式查找重复项,也许是这样的:
START n=node(*)
WHERE HAS(n.externalId)
WITH n
ORDER BY ID(n) ASC
WITH count(*) AS occurrences, n.externalId AS externalId, collect(ID(n)) AS ids
WHERE occurrences > 1
RETURN externalId, TAIL(ids)
我正在尝试以编程方式定位 Neo4j 1.8 数据库中的所有重复节点(使用 Neo4j 1.8)。
需要检查的节点都有一个(非索引)属性 externalId
,我想为其找到重复项。这是我得到的 Cypher 查询:
START n=node(*), dup=node(*) WHERE
HAS(n.externalId) AND HAS(dup.externalId) AND
n.externalId=dup.externalId AND
ID(n) < ID(dup)
RETURN dup
数据中的节点数少于 10K,带有 externalId
的节点数少于 1K。
上面的查询正在运行,但似乎表现不佳。有没有内存消耗更少的方法来做到这一点?
试试这个查询:
START n=node(*)
WHERE HAS(n.externalId)
WITH n.externalId AS extId, COLLECT(n) AS cn
WHERE LENGTH(cn) > 1
RETURN extId, cn;
它避免了节点的笛卡尔积。它找到不同的 externalId
值,收集具有相同 id 的所有节点,然后过滤掉不重复的 id。结果中的每一行都将包含一个 externalId 和具有该 ID 的重复节点的集合。
start 子句包括全图扫描,然后组装整个节点集的笛卡尔积(从 10k * 10k = 100m 对开始),然后根据中的标准缩小这个非常大的列表where 子句。 (也许这里有密码优化?我不确定)
我认为在 externalId 上添加索引将是一个明显的胜利,并且目前可能会提供足够的性能提升,但您也可以考虑以不同的方式查找重复项,也许是这样的:
START n=node(*)
WHERE HAS(n.externalId)
WITH n
ORDER BY ID(n) ASC
WITH count(*) AS occurrences, n.externalId AS externalId, collect(ID(n)) AS ids
WHERE occurrences > 1
RETURN externalId, TAIL(ids)