一组节点之间的 Neo4J 连接和推荐
Neo4J connectivity and recommendation among a set of nodes
我的数据库包含一组节点和一种数字类型的关系。给定一组节点,我想看看它们是否以及如何相互连接,以及找到可以包含的节点。很抱歉无法合成一个数据。你可以把每个节点想象成一个城市,关系就是一个距离。如果关系不存在,意味着没有从城市 A 到 B 的直接方式。这个想法有两个方面 1) 找出这些城市是否连接以及如何连接。 2) 寻找其他中间城市。
例如,如果我有 A、B、C、D 和 E - 一种方法是进行成对的最短距离。该图是无方向的,因此 A-B 与 B-A 相同。
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 中是否有任何其他概念可以进行此类分析,如果没有,您如何确保每一对的输出都是不同的,这意味着没有 A-B 和 B-A 出来,而只有其中一个。
当然,如果您有一组数据,并且想对不包含重复项的唯一集执行某些操作,那么最好先生成该唯一项集,然后将其传递给您的查询,这样您不必执行不必要的查询然后丢弃冗余信息。
要生成唯一的一对集,您可以这样做。
// 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 + ", ")
此查询将 return 您的 "destinations" 组路径中的最小路径集,没有任何重复。
我的数据库包含一组节点和一种数字类型的关系。给定一组节点,我想看看它们是否以及如何相互连接,以及找到可以包含的节点。很抱歉无法合成一个数据。你可以把每个节点想象成一个城市,关系就是一个距离。如果关系不存在,意味着没有从城市 A 到 B 的直接方式。这个想法有两个方面 1) 找出这些城市是否连接以及如何连接。 2) 寻找其他中间城市。
例如,如果我有 A、B、C、D 和 E - 一种方法是进行成对的最短距离。该图是无方向的,因此 A-B 与 B-A 相同。
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 中是否有任何其他概念可以进行此类分析,如果没有,您如何确保每一对的输出都是不同的,这意味着没有 A-B 和 B-A 出来,而只有其中一个。
当然,如果您有一组数据,并且想对不包含重复项的唯一集执行某些操作,那么最好先生成该唯一项集,然后将其传递给您的查询,这样您不必执行不必要的查询然后丢弃冗余信息。
要生成唯一的一对集,您可以这样做。
// 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 + ", ")
此查询将 return 您的 "destinations" 组路径中的最小路径集,没有任何重复。