【问题标题】:Complex Cypher Traversal with Math复杂的密码遍历与数学
【发布时间】:2023-02-02 10:01:14
【问题描述】:

我对 Neo4j 和图形数据库比较陌生,所以请多多包涵。

我想以最有效的方式遍历我们的 Neo4j 数据库。遍历时,我需要沿途对边及其值进行一些数学运算。在规模上,我们的数据库可能有数百万个节点和边缘,所以我非常关心效率。

我的数据库中有一些人被“标记”的节点。而且这些人之间还有交易。请参见下图。在我的算法中,我基本上会带走任何人,看看他们从每个标记的人那里收到了多少钱。

到目前为止,我一直在使用Neo4j python driverneomodel 来执行这些遍历。

为此,我创建了一种算法,它基本上是递归深度优先遍历的修改版本。我递归地越来越深入地遍历节点的发送者,直到我不能再遍历为止。当我遇到一个“被标记的人”(例如我想追踪他的钱的罪犯)时,我为他们添加一条记录。

当递归回到源头时,我反复将资金来源乘以给定节点从其发送方收到的金额的分数。例如,当递归返回到 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}

所以我有以下问题:

  1. 是否可以使用密码查询进行这种类型的遍历?从我最初的调查来看,似乎并非如此。
  2. 我见过有人使用 gremlin 来执行类似的复杂图形查询。这值得研究吗?
  3. 是否有任何其他工具可以更好地满足我们的需求来处理具有类似复杂数据模型的计算?
  4. 有没有我可以使用或改编的另一种著名的图形算法来执行相同的任务?

    任何想法或 cmets 将不胜感激。谢谢!

【问题讨论】:

    标签: neo4j cypher gremlin graph-databases graph-data-science


    【解决方案1】:

    似乎可以用variable length patterns'reduce'case-when来表示,以模拟“这是否是犯罪分子”的三元组。随着规划器的改进,gremlin 似乎已经半途而废了;这似乎是查询规划器不应该纠结的事情,因为无论如何您最终都需要接触大部分或所有节点。但是假设你的图表没有循环,这似乎也像 Python 应该足够快,至少对于批量分析和针对预先计算的集合的缓存临时查询。给定合理的内存表示,数百万个节点应该可以轻松地装入内存。

    This answer 可能会让您入门。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多