添加许多节点属性时在 NEO4J 中加载数据缓慢

Loading data slow in NEO4J when adding many node properties

我正在尝试可视化防火墙日志数据。首先,我使用 Windows 应用程序防火墙日志。

我正在使用 LOAD CSV WITH HEADERS。当我只有有限数量的关系属性时效果很好,但是只要我再添加一个 属性 到关系中,它就会变慢,需要 30 分钟以上的时间来处理。

下面的示例加载很快:

        $queries['statements'] = @()

        $query = "LOAD CSV WITH HEADERS FROM 'file:///data/go_output/$($uuid)_send_data.csv' AS row
        MERGE (from:ipobj {ip: row.srcip, ipversion: row.srcipver, internal: row.srcipinternal})
        MERGE (to:ipobj {ip: row.dstip, ipversion: row.dstipver, internal: row.dstipinternal})
        MERGE (from)-[datatransfer:SENT {date: row.date, type: row.action, size: row.size}]->(to)"
        $queries['statements'] += [ordered]@{'statement'="$($query)"}

        $retval = $queries| ConvertTo-Json

        $url = "http://127.0.0.1:7474"
        $credPair = "neo4j:test"
        $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($credPair))
        $headers = @{"Authorization"="Basic $encodedCredentials"; "Accept"="application/json; charset=UTF-8";"Content-Type"="application/json"}

        $response = Invoke-WebRequest -Uri "$($url)/db/data/transaction/commit" -Method Post -Headers $headers -Body $($retval)
        $response.content

下面的示例需要 15 分钟来处理:

        $queries = @{}
        $queries['statements'] = @()

        $query = "LOAD CSV WITH HEADERS FROM 'file:///data/go_output/$($uuid)_send_data.csv' AS row
        MERGE (from:ipobj {ip: row.srcip, ipversion: row.srcipver, internal: row.srcipinternal})
        MERGE (to:ipobj {ip: row.dstip, ipversion: row.dstipver, internal: row.dstipinternal})
        MERGE (from)-[datatransfer:SENT {date: row.date, type: row.action, size: row.size, srcport: row.srcport, dstport: row.dstport}]->(to)"
        $queries['statements'] += [ordered]@{'statement'="$($query)"}

        $retval = $queries| ConvertTo-Json

        $url = "http://127.0.0.1:7474"
        $credPair = "neo4j:test"
        $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($credPair))
        $headers = @{"Authorization"="Basic $encodedCredentials"; "Accept"="application/json; charset=UTF-8";"Content-Type"="application/json"}

        $response = Invoke-WebRequest -Uri "$($url)/db/data/transaction/commit" -Method Post -Headers $headers -Body $($retval)
        $response.content

NEO4j 抱怨一个急切的运算符,但加载只找到 3 个属性。

帮忙?我不知道为什么会这样。我检查了查询计划并进行了一系列故障排除,但不知道为什么会这样。为避免此 post 太长,我不会进行故障排除,但请随时询问或告诉我我做错了什么!

注意 我正在加载的文件或多或少是一个标准问题 windows 防火墙 (pfirewall.log) 文件,具有以下修改:

Eager 运算符用于保留 Cypher 语义,但由于其在处理大型数据集(例如使用 LOAD CSV)时的后果而变得令人头疼。有计划的更改来缓解这种情况,但那是为了将来。

更多信息在这里: https://community.neo4j.com/t/cypher-sleuthing-the-eager-operator/10730

对于解决方法,我们可以在查询中做一些扭曲,或者更容易地,将其分成 3 遍:一次合并您的 from 节点,一次合并您的 to 节点,第三个匹配两者,然后合并它们之间的关系。

编辑:

感谢您提供的查询计划,我们可以看到您的 MERGE 没有索引支持,这就是我们在计划中看到 NodeByLabelScans 的原因。 每行,对于两个节点中的每一个,每一个 :ipobj 节点都被检查和过滤,这不会很有效。

你需要一个索引来加快速度。

什么唯一标识 :ipobj 节点?如果它只是 ip 属性 然后创建一个唯一的约束。如果它是属性的组合,则创建一个节点键约束,或者至少在给定属性上创建一个索引。

我关于解决 Eager 问题的评论仍然有效,但您需要使用索引或约束来支持您的 MATCH 和 MERGE(尤其是在执行加载时!)以提高它们的效率。