在数百万节点之间创建关系的优化方式

问题描述 投票:0回答:2

我将节点上传到 neo4j,每个节点都具有

email
phone
address
等属性。如果节点属性之间的 levenshtein 距离总和小于 a,我需要在两个节点之间创建关系阈值。如何以更优化的方式做到这一点?目前,我正在这样做:

MATCH (p1:sample500K) WITH p1 
MATCH (p2:sample500K)
WHERE id(p1) <id(p2)
AND (
  apoc.text.levenshteinDistance(p1.email, p2.email) + 
  apoc.text.levenshteinDistance(p1.phone, p2.phone) + 
  apoc.text.levenshteinDistance(p1.mobilephone, p2.mobilephone) +
  apoc.text.levenshteinDistance(p1.street, p2.street)) <= $threshold
MERGE (p1)-[:SAME_USER500K]->(p2)

我也尝试过 apoc.periodic.iterate 这也需要时间。另外,我需要在 python 中运行查询。

有人可以建议更好的方法或需要进行任何更改吗?

neo4j cypher neo4j-apoc
2个回答
0
投票

这是一个根本上呈指数级增长的难题;更多的输入数据将导致更多的可能性使用类似暴力的方法进行检查。

因此,我建议将您的方法分为两步:

  1. 根据输入数据生成向量表示。我自己的搜索表明,您可以将字符串输入数据传递给 n-gram 函数来获取原始字符串的小块,然后将其传递给 tf-idf 函数以获得实际的向量。对所有输入参数执行此操作,确保向量始终具有相同的长度,合并它们并将它们放入向量数据库中。
  2. 在矢量数据库中执行矢量相似性搜索以获得相似的记录,这可能满足您的编辑距离要求。然后像时尚一样用蛮力检查您对每个返回元素的要求。

这种方法应该会大大减少您必须执行的检查量,但需要矢量数据库。我认为 Neo4j 具有基本的矢量功能,但我不确定它们有多好。关键方面是向量相似性搜索本身。

注意:如果某些 n-gram-片段不是另一个 n-gram-结果的一部分,则 n-gram-data 到向量的步骤可能不一致。这可能需要一些测试或更多标准化,不确定。


0
投票

子查询或嵌套查询通常运行得更快。比如...

MATCH (p1:sample500K) WITH collect(p1) as pp1
unwind pp1 as x
call
{
  with x
  MATCH (p2:sample500K)
  WHERE id(x) <id(p2)
AND (
  apoc.text.levenshteinDistance(x.email, p2.email) + 
  apoc.text.levenshteinDistance(x.phone, p2.phone) + 
  apoc.text.levenshteinDistance(x.mobilephone, p2.mobilephone) +
  apoc.text.levenshteinDistance(x.street, p2.street)) <= $threshold
MERGE (x)-[:SAME_USER500K]->(p2)
}

双重嵌套可能会运行得更快?

© www.soinside.com 2019 - 2024. All rights reserved.