在Neo4J中为大图生成边缘的智能方法

时间:2016-05-10 11:00:26

标签: graph neo4j cypher

我想从csv文件生成图表。行是顶点,列是属性。我想通过某种方式通过顶点上的相似性(不一定是权重)来生成边缘,当两个顶点具有相同的某个属性值时,这两个顶点之间的边将具有值为1或true的相同属性。 / p>

发生在我身上的最简单的密码查询看起来有点像这样:

Match (a:LABEL), (b:LABEL)
WHERE a.attr = b.attr
CREATE (a)-[r:SIMILAR {attr : 1}]->(b)

图表有大约148000个顶点,Java Heap Size选项是:根据可用的系统资源动态计算。

我发布的查询为Neo.DatabaseError.General.UnknownFailure提供了上面的Java堆空间提示。

我能想到的一个问题是,首先构建一个巨大的笛卡尔积,然后寻找匹配来创建边。有更聪明的,也许是连续的方式吗?

2 个答案:

答案 0 :(得分:2)

我认为你需要一点改变模型:不需要通过特定属性的值将每个节点彼此连接起来。最好有一个中间节点,您将使用相同的值属性绑定节点。

这可以在导出时或之后完成。

例如:

Match (A:LABEL) Where A.attr Is Not Null
Merge (S:Similar {propName: 'attr', propValue: A.attr})
Merge (A)-[r:Similar]->(S)

稍后使用单独的查询,您可以删除只有一个连接的类似节点(没有其他节点具有相同的此属性值):

Match (S:Similar)<-[r]-()
With S, count(r) As r Where r=1 
Detach Delete S

如果您需要通过所有道具连接,您可以使用下一个查询:

Match (A:LABEL) Where A.attr Is Not Null
With A, Keys(A) As keys
  Unwind keys as key
    Merge (S:Similar {propName: key, propValue: A[key]})
    Merge (A)-[:Similar]->(S)

答案 1 :(得分:1)

你是正确的,将生产一种huuuge笛卡儿产品。

您可以批量迭代1000个节点,例如,通过在每次迭代时递增SKIP值直到它返回0来运行查询。

MATCH (a:Label)
WITH a LIMIT SKIP 0 LIMIT 1000
MATCH (b:Label)
WHERE b.attr = a.attr AND id(b) > id(a)
CREATE (a)-[:SIMILAR_TO {attr: 1}]->(b)
RETURN count(*) as c