gpt4 book ai didi

neo4j - 获取每个关系深度的节点数

转载 作者:行者123 更新时间:2023-12-01 09:00:24 24 4
gpt4 key购买 nike

我正在从事一个项目,其中每个用户都表示为 Neo4j 中的一个节点。用户可以“认可”其他用户,从而建立关系。我希望能够根据用户的信任度对用户进行排名,其中每个关系的权重都基于支持他们的用户的权重。例如,一个得到 20 多个用户认可的用户应该比另一个只有几个认可的用户对自己的认可有更多的权重。

我现在查询它的方式给了我每个深度的节点数,但它没有按父节点分组(例如,所有 3 级节点都在一个数组中返回,你不知道级别 2 中的哪些节点每个都相关)。

MATCH (n)-[r:TRUSTS*]->(u)
WHERE u.name = 'XYZ' WITH n.name AS n, LENGTH(r) AS depth
RETURN COLLECT(DISTINCT n) AS endorsers, depth
ORDER BY depth

这是网络的样子,以及对 Ben 的查询结果。

enter image description here enter image description here

如您所见,Ben 有 2 个一级背书人,JM 有两个二级背书人,从图中可以看出,但不是来自查询结果。

任何人都可以建议如何返回按父节点和深度分组的结果,以便我可以在我的代码中计算信任排名,或者更好的方法来执行加权平均以实现第一段中的目标?

这是我为 Ben 想象的那种树结构输出的示例:

Ben
├── JM
│ ├── Simon
│ └── Rus
│ ├── Robbie
│ │ ├── Ben
│ │ │ └──/ should terminate here
│ │ ├── Simon
│ │ └── JM
│ └── Ben
│ └──/ should terminate here
└── Simon

这是 Rus 的另一个:

Rus
├── Robbie
│ ├── Simon
│ ├── Ben
│ │ ├── Simon
│ │ └── JM
│ │ ├── Simon
│ │ └── Rus
│ └── JM
│ ├── Simon
│ └── Rus
└── Ben
├── Simon
└── JM
├── Simon
└── Rus

显然它应该在到达我查询的用户时终止(否则它将是一个循环结构)。


我找到的最接近的匹配是 Tezra 提供的查询,它是:

MATCH (target:User{name:"Rus"}), (person:User), p=((person)-[:TRUSTS*]->(target))
WHERE ALL(n in NODES(p)[1..-1] WHERE n<>target)
RETURN NODES(p)[-2].name as endorser, COLLECT(person.name) as endorsed_by, SIZE(RELATIONSHIPS(p)) as depth
ORDER BY depth

此查询返回“Rus”的一级背书,然后返回 n 级背书一级背书:

| endorser | endorsed_by           | depth |
|----------|-----------------------|-------|
| Robbie | Robbie | 1 | // 1st level endorsers of Rus
| Ben | Ben | 1 | // 1st level endorsers of Rus

| Robbie | JM, Simon, Ben | 2 | // 1st level endorsers of Robbie
| Ben | JM, Simon | 2 | // 1st level endorsers of Ben

| Ben | Rus, Simon | 3 | // 2nd level endorsers of Ben
| Robbie | Rus, Simon, JM, Simon | 3 | // 2nd level endorsers of Robbie

| Robbie | Rus, Simon | 4 | // 3rd level endorsers of Robbie

这不太正确,您只知道谁间接背书了 Ben 和 Robbie,而不知道中间的节点。

例如,从该输出我们知道 Robbie 的一级背书人是 JMSimonBen。第 2 级背书人是 RusSimonJMSimon(树中的第 4 列),但是有无法知道一级和二级背书人之间的关系。就此查询而言,以下树是相同的:

Rus
└── Robbie
├── Simon
├── Ben <--- here Ben has 3 children (so should be weighted higher)
│ ├── Simon
│ ├── Rus
│ └── JM
└── JM
└── Simon


Rus
└── Robbie
├── Simon
├── Ben
│ └── Simon
└── JM <--- here JM has 3 children instead
├── Simon
├── Rus
└── JM

我正在寻找的是一个查询,它返回类似这样的东西(每个背书的父级可以重建完整的树),这是 Rus 的想象输出:

+--------+----------+-------+
| parent | children | depth |
+--------+----------+-------+
| Rus | Robbie | 1 |
+--------+----------+-------+
| Rus | Ben | 1 |
+--------+----------+-------+
| Robbie | Simon | 2 |
+--------+----------+-------+
| Robbie | Ben | 2 |
+--------+----------+-------+
| Robbie | JM | 2 |
+--------+----------+-------+
| Ben | Simon | 3 |
+--------+----------+-------+
| Ben | JM | 3 |
+--------+----------+-------+
| JM | Simon | 4 |
+--------+----------+-------+
| JM | Rus | 4 |
+--------+----------+-------+
| JM | Simon | 3 |
+--------+----------+-------+
| JM | Rus | 3 |
+--------+----------+-------+
| Ben | Simon | 2 |
+--------+----------+-------+
| Ben | JM | 2 |
+--------+----------+-------+
| JM | Simon | 3 |
+--------+----------+-------+
| JM | Rus | 3 |
+--------+----------+-------+

最佳答案

首先,这是一个console播放/测试数据。

这里有一些评论查询。让我知道哪个最能满足您的需求。 (按相关性排序)

// Match the query target, and everyone who can endorse
MATCH (target:User{name:"Ben"}), (person:User),

// Match all endorse chains, length limit 5
p=((person)-[:TRUSTS*..5]->(target))

// Our target may start, and will end; our chain, so no other path nodes can be him.
// Normal matching will not match cycles.
// Adjust further path termination conditions here.
WHERE ALL(n in NODES(p)[1..-1] WHERE n<>target)

// Return target (extra), the 1'st tier endorser, their endorsers, and rank(depth) of each of those endorsers.
RETURN target.name, NODES(p)[-2] as endorser, COLLECT(person.name), SIZE(RELATIONSHIPS(p)) as depth
ORDER BY depth

// one line copy for copy-paste into console
MATCH (target:User{name:"Ben"}), (person:User), p=((person)-[:TRUSTS*..5]->(target)) WHERE ALL(n in NODES(p)[1..-1] WHERE n<>target) RETURN target.name, NODES(p)[-2] as endorser, COLLECT(person.name), SIZE(RELATIONSHIPS(p)) as depth ORDER BY depth

另一种返回格式

WITH NODES(p)[-2] as endorser, {people:COLLECT(person.name), depth:SIZE(RELATIONSHIPS(p))} as auth 
RETURN endorser, COLLECT(auth)

// one line copy for copy-paste into console
MATCH (target:User{name:"Ben"}), (person:User), p=((person)-[:TRUSTS*..5]->(target)) WHERE ALL(n in NODES(p)[1..-1] WHERE n<>target) WITH NODES(p)[-2] as endorser, {people:COLLECT(person.name), depth:SIZE(RELATIONSHIPS(p))} as auth RETURN endorser, COLLECT(auth)

更新:替代返回格式以匹配 OP 的返回表

MATCH (target:User{name:"Rus"}), (person:User), p=((person)-[:TRUSTS*]->(target)) WHERE ALL(n in NODES(p)[1..-1] WHERE n<>target) WITH NODES(p) as n, SIZE(RELATIONSHIPS(p)) as depth RETURN DISTINCT n[-depth] as parent, n[-depth-1] as child, depth ORDER BY depth

关于neo4j - 获取每个关系深度的节点数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46589975/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com