neo4j - 一组节点之间的 Neo4J 连接和推荐
问题描述
我的数据库包含一组节点和一个数字类型的关系。给定一组节点,我想看看它们是否以及如何相互连接,并找到可以包含的节点。很抱歉无法合成数据。你可以把每个节点想象成一个城市,关系就是一个距离。如果关系不存在,则意味着从城市 A 到 B 没有直接的路径。这个想法有两个方面 1) 找出这些城市是否以及如何连接。2)寻找其他中间城市。
例如,如果我有 A、B、C、D 和 E - 一种方法是做一个成对的最短距离。该图是无方向的,因此 AB 与 BA 相同。
MATCH (n:people {name:'A'})-[r:INTERACTION]-(n2:people {name:'B'}),
p = shortestPath ((n)-[*]-(n2))
RETURN p
但是,(n*n-1)/2
我可以做这样的事情,而不是那样做:
MATCH (n:people)-[r:INTERACTION]-(n2:people)
MATCH spath=shortestPath ((n)-[*]-(n2))
WHERE n.name in ['A', 'B', 'C', 'D', 'E'] and n2.name in ['A', 'B', 'C', 'D', 'E']
RETURN DISTINCT n.name, n2.name, r.score
尽管如此,对于第二个目标,寻找其他中间城市,我想知道在 neo4j 中是否有任何其他概念可以进行此类分析,如果没有,您将如何确保每对的输出是不同的,这意味着没有 AB和BA出来的,而只是其中之一。
解决方案
当然,如果您有一组数据,并且您想对不包含重复项的唯一集执行某些操作,那么最好先生成该唯一项集,然后将其传递给您的查询,这样您就不必执行不必要的查询,然后丢弃冗余信息。
要生成一组独特的对组,您可以执行以下操作。
// unwind the name collection twice to get all combinations
WITH ['A', 'B', 'C', 'D', 'E'] AS names
UNWIND names AS name1
UNWIND names AS name2
// makes sure the pairs are ordered and ignore identical pairs
WITH CASE
WHEN name1 = name2 THEN NULL
WHEN name2 < name1 THEN [name2, name1]
ELSE [name1, name2]
END AS pair
// collect all of the pairs
RETURN COLLECT (DISTINCT pair) AS pairs
如果您使用的是 APOC,则可以将其替换为
WITH ['A', 'B', 'C', 'D', 'E'] AS names
RETURN apoc.coll.combinations(names, 2) AS pairs
把它和你的查询放在一起,你可以做这样的事情......
// from above
WITH ['A', 'B', 'C', 'D', 'E'] AS names
UNWIND names AS name1
UNWIND names AS name2
WITH CASE WHEN name1 = name2 THEN NULL WHEN name2 < name1 THEN [name2, name1] ELSE [name1, name2] END AS pair
WITH COLLECT (DISTINCT pair) AS pairs
// iterate over the unique pairs
UNWIND pairs AS pair
// find the shortest path
// from
// the first node identified by the first value in the pair
// to
// the second node identified by the second value in the pair
MATCH spath = shortestPath((:people {name: pair[0]} )-[*..5]-(:people {name: pair[1]} ))
// produce a string representation of each path
RETURN reduce(string = "", rel in relationships(spath) | string + startNode(rel).name + " " + type(rel) + " " + endNode(rel).name + ", ")
此查询将返回您的“目的地”集中的最小路径集,而不会重复。
推荐阅读
- html - 仅在悬停时显示文本
- ubuntu - 是否可以在 Ubuntu 上使用 Azure AD 使用 sqlalchemy 和 Python 连接到 Azure SQL?
- c# - 动态按钮的事件处理程序未触发
- javascript - 从 node.js 中的 xml 检索数据
- c# - 将枚举添加到数组并发布到数据库
- actionscript-3 - 来自 http 查询字符串的 AS3 变量
- node.js - 纽约市覆盖率未生成/摩卡单元测试未运行
- cuda - 如何减少 CUDA 上下文大小(多进程服务)
- java - 字符串索引超出范围 - java
- node.js - 使用 React Ui、Node Server 和 Python API 实现推送通知