在持续更新的数据上使用algo.similarity.jaccard时,防止重复的SIMILAR关系

时间:2018-12-12 20:21:27

标签: graph neo4j similarity

我正在使用Neo4j图算法库中的algo.similarity.jaccard算法为图中的一类节点计算Jaccard相似性指数。一旦计算了Jaccard相似度并指示了截止,我就将度量存储在节点之间的关系中(这是算法的功能)。我试图查看图表随时间的变化,因为我将要添加的新数据添加到图中(我将使用新数据重新加载CSV文件并合并到新的节点/关系中。)

我可以预见的一个问题是,一旦我使用更新后的图再次运行Jaccard算法,它将创建重复的关系。这是我正在使用的代码的Neo4j文档示例:

MATCH (p:Person)-[:LIKES]->(cuisine)
WITH {item:id(p), categories: collect(id(cuisine))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard(data, {topK: 1, similarityCutoff: 0.1, write:true})
YIELD nodes, similarityPairs, write, writeRelationshipType, writeProperty, min, max, mean, stdDev, p25, p50, p75, p90, p95, p99, p999, p100
RETURN nodes, similarityPairs, write, writeRelationshipType, writeProperty, min, max, mean, p95

是否有一种方法可以指定我每次使用更新的图形运行此代码时都不希望重复的关系?手动地,我会使用MERGE而不是CREATE,但是看到这似乎是库中的算法,我不确定该如何去做。仅供参考,我将无法向库插件添加更改,并且似乎无法将关系存储在其他标签下,例如SIMILARITY2。

1 个答案:

答案 0 :(得分:0)

至少有两种方法可以避免多次调用algo.similarity.jaccard产生重复关系:

  1. 在每次调用之前删除现有关系(默认情况下,其类型为SIMILAR)。这可能是最简单的方法。

  2. 在进行调用时忽略write:true选项(以使该过程根本不会创建关系),并编写自己的Cypher代码以可选地创建尚不存在的关系(使用{ {1}}。

[已更新]

以下是第二种方法的示例(使用 MERGE过程的变体,它会为我们的目的提供更多有用的值):

algo.similarity.jaccard.stream

由于该过程将两次返回相同的节点对(具有相同的MATCH (p:Person)-[:LIKES]->(cuisine) WITH {item:id(p), categories: collect(id(cuisine))} as userData WITH collect(userData) as data CALL algo.similarity.jaccard.stream(data, {topK: 1, similarityCutoff: 0.1}) YIELD item1, item2, similarity WHERE item1 < item2 WITH algo.getNodeById(item1) AS n1, algo.getNodeById(item2) AS n2, similarity MERGE (n1)-[s:SIMILAR]-(n2) SET s.score = similarity RETURN * 分数),因此similarity子句用于过滤出一对节点,以加快处理速度。 WHERE实用程序功能用于通过其本机ID获取节点。并且algo.getNodeById()子句的关系模式没有为MERGE指定值,因此即使其具有不同的值,它也将匹配现有关系。用于设置score的{​​{1}}子句放在SET之后,这也有助于确保该值是最新的。