Neo4j:有人可以 "translate" 这个代码片段给我吗?

Neo4j: Could someone "translate" this code snippet for me?

如果我没有遵循这里的最佳实践,我很抱歉,但我无法理解(因此当然也不会在新版本的 Neo4j 中重新创建)这个片段应该做什么:(

出于兴趣,我开始了我的 Neo4j 之旅并结束了介绍 类 并想重新创建一些项目以更加熟练地使用这项有趣的技术。 但是我无法从“What's cooking”示例中了解这个练习:

// Construct lists of node ids of ingredients, 
// grouped by node ids of recipes 
MATCH (r:Recipe)-[:CONTAINS_INGREDIENT]->(ingredient)
WITH {item:id(r), categories: collect(id(ingredient))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard.stream(data)
YIELD item1, item2, count1, count2, intersection, similarity

// Look up nodes by node id
WITH algo.asNode(item1) AS from, 
     algo.asNode(item2) AS to, 
     similarity, intersection 
RETURN from.name, from.id, to.name, to.id, intersection, similarity
ORDER BY similarity DESC
LIMIT 20

当我尝试用 gds.nodeSimilarity.stream 和 [= 更新过时的 algo.similarity.jaccard() 24=]algo.asNode() 和 gds.asNode(),我在 YIELD 之后仍然失败控制台告诉我的语句,它只是找不到 item1(因此也找不到 item2)。

编辑:我是 运行 Neo4j 版本 4.2.5 和 GDS 1.5.2

我希望有人能帮助我了解哪里出了问题!

BR, 旦

你是对的,你的例子来自旧的算法库,而不是当前的 GDS 库。以下是示例代码的功能细分。

首先将食谱与其所含成分相匹配。

// Construct lists of node ids of ingredients, 
// grouped by node ids of recipes 
MATCH (r:Recipe)-[:CONTAINS_INGREDIENT]->(ingredient)

此时,我们有一个 tall 结果集,由一对 r 个食谱节点和 ingredient 个成分节点组成。

WITH {item:id(r), categories: collect(id(ingredient))} as userData

现在我们已经转换了结果,所以每个配方都有一张地图。该地图有两个 key-value 对。 item 键指向配方节点的 ID。 categories 键指向成分节点的所有 ID 的列表。

WITH collect(userData) as data

我们再次将结果从每行一张地图的多行转换为单行。该行包含一个名为 data 的列表,其中包含所有地图。这是 algo.similarity.jaccard.stream 期望作为输入的格式。现在我们可以调用算法了。

CALL algo.similarity.jaccard.stream(data)
YIELD item1, item2, count1, count2, intersection, similarity

算法输出item1和item2。这些是 Neo4j 的内部节点 ID。这些 id 在 Neo4j 之外没有意义,所以我们想通过调用 algo.asNode

将它们转换回节点
// Look up nodes by node id
WITH algo.asNode(item1) AS from, 
     algo.asNode(item2) AS to, 
     similarity, intersection 

现在我们可以return我们感兴趣的节点属性。

RETURN from.name, from.id, to.name, to.id, intersection, similarity
ORDER BY similarity DESC
LIMIT 20

要在当前的 Graph Data Science 库中做类似的事情,您可以使用 Node Similarity algorithm。 GDS 算法不是期望地图列表,而是接受 in-memory 图形投影作为输入。创建一个名为 recipe-graph 的 in-memory 图,其中包含 RecipeIngredient 节点以及 CONTAINS_INGREDIENT 关系。

CALL gds.graph.create('recipe-graph', ["Recipe", "Ingredient"], 'CONTAINS_INGREDIENT')

然后,将该图传递给 nodeSimilarity 算法。

CALL gds.nodeSimilarity.stream('recipe-graph')
 YIELD node1, node2, similarity
 WITH gds.util.asNode(node1) AS r1, 
    gds.util.asNode(node2) AS r2, similarity
 WHERE r1:Recipe and r1:Recipe
 RETURN r1.name as recipe1, r2.name as recipe2, similarity
 ORDER BY similarity DESCENDING, r1.name, r2.name
 LIMIT 20

最后,放下您创建的 in-memory 图表。

CALL gds.graph.drop('recipe-graph')

如果您不想创建和删除命名图,也可以在 anonymous graph.

上调用算法