【发布时间】:2023-02-02 10:01:14
【问题描述】:
我对 Neo4j 和图形数据库比较陌生,所以请多多包涵。
我想以最有效的方式遍历我们的 Neo4j 数据库。遍历时,我需要沿途对边及其值进行一些数学运算。在规模上,我们的数据库可能有数百万个节点和边缘,所以我非常关心效率。
我的数据库中有一些人被“标记”的节点。而且这些人之间还有交易。请参见下图。在我的算法中,我基本上会带走任何人,看看他们从每个标记的人那里收到了多少钱。
到目前为止,我一直在使用Neo4j python driver 和neomodel 来执行这些遍历。
为此,我创建了一种算法,它基本上是递归深度优先遍历的修改版本。我递归地越来越深入地遍历节点的发送者,直到我不能再遍历为止。当我遇到一个“被标记的人”(例如我想追踪他的钱的罪犯)时,我为他们添加一条记录。
当递归回到源头时,我反复将资金来源乘以给定节点从其发送方收到的金额的分数。例如,当递归返回到 John 时,我首先将 Sally 的所有来源乘以 Sally 的钱被发送给 John 的比例,在本例中为 (3/17),因为 Sally 收到 17 美元并向 John 发送了 3 美元.然后,我将对 Frank 的消息来源执行相同的操作。我将他的每个来源乘以 (2/11),因为 Frank 从 Frank 那里收到了 11 美元,而 John 从 Frank 那里收到了 2 美元。
这是我为执行此算法而编写的 python 代码:
def get_sources(node):
source_record = {}
for sender in node.senders:
# retrieve the edge between these two nodes
transaction = node.senders.relationship(sender)
amount_from_sender = transaction.value
sender_total_received = sender.total_received()
if isinstance(sender, MarkedPerson): # Base Case
source_record[sender.name] = amount_from_sender
if len(sender.senders) > 0: # Recursive Case
sender_sources = get_sources(sender)
for source_name, source_value in sender_sources.items():
# find what fraction of the sender's money they sent to 'node', then
# multiply this by how much money the sender has of this source to find
# how much money 'node' has from the source
amount_from_source = (amount_from_sender / sender_total_received) * source_value
if source_name in source_record:
source_record[source_name] += amount_from_source
else:
source_record[source_name] = amount_from_source
return source_record
以下是它给出的结果的一些示例:
查询 John 时的结果:{'Bill': 2.310160427807487, 'Rob': 2.6898395721925135}
查询约翰的结果:{'Bill': 2.310160427807487, 'Rob': 2.6898395721925135, 'Sal': 2.6898395721925135}
所以我有以下问题:
- 是否可以使用密码查询进行这种类型的遍历?从我最初的调查来看,似乎并非如此。
- 我见过有人使用 gremlin 来执行类似的复杂图形查询。这值得研究吗?
- 是否有任何其他工具可以更好地满足我们的需求来处理具有类似复杂数据模型的计算?
- 有没有我可以使用或改编的另一种著名的图形算法来执行相同的任务?
任何想法或 cmets 将不胜感激。谢谢!
【问题讨论】:
标签: neo4j cypher gremlin graph-databases graph-data-science