Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用neo4jclient的性能问题_C#_Neo4j_Neo4jclient - Fatal编程技术网

C# 使用neo4jclient的性能问题

C# 使用neo4jclient的性能问题,c#,neo4j,neo4jclient,C#,Neo4j,Neo4jclient,我目前正在为我所在行业的一些流程探索图形数据库的潜力。 一周前我开始使用Neo4Jclient,因此我低于标准初学者:-) 我对Neo4J非常兴奋,但我面临着巨大的性能问题,我需要帮助 我的项目的第一步是从现有文本文件填充Neo4j。 这些文件由使用简单模式格式化的行组成: StringID=StringLabel(String1,String2,...,StringN); 我考虑下面的行: #126=TYPE1(#80,#125); 我想创建一个标签为“TYPE1”的节点和两个属性: 1)

我目前正在为我所在行业的一些流程探索图形数据库的潜力。 一周前我开始使用Neo4Jclient,因此我低于标准初学者:-)

我对Neo4J非常兴奋,但我面临着巨大的性能问题,我需要帮助

我的项目的第一步是从现有文本文件填充Neo4j。 这些文件由使用简单模式格式化的行组成:

StringID=StringLabel(String1,String2,...,StringN);
<如果>我考虑下面的行:

#126=TYPE1(#80,#125);
我想创建一个标签为“TYPE1”的节点和两个属性: 1) 在上面的示例中,使用ObjectID:#126”的唯一ID 2) 包含将来使用的所有参数的字符串:上例中的“#80,#125”

我必须考虑我将处理多个前向引用,如下面的例子:

#153=TYPE22('0BTBFw6f90Nfh9rP1dl_3P',#144,#6289,$);
稍后将在文件中解析使用StringID“#6289”定义节点的行

因此,为了解决文件导入问题,我定义了以下类:

public class myEntity
{
    public string propID { get; set; }
    public string propATTR { get; set; }

    public myEntity()
    {
    }
}
感谢我的文本文件中的转发引用(毫无疑问,我的Neo4J知识很差…) 我决定分三步工作:

第一个循环,我从文件中解析的每一行strLABEL、strID和strATTRIBUTES中提取, 然后,我使用以下代码为每行添加一个Neo4j节点:

strLabel = "(entity:" + strLABEL + " { propID: {newEntity}.propID })";
graphClient.Cypher
    .Merge(strLabel)
    .OnCreate()
    .Set("entity = {newEntity}")
    .WithParams(new { 
        newEntity = new {
            propID = strID,
            propATTR = strATTRIBUTES
        }
    })
    .ExecuteWithoutResults();
var queryNode = graphClient.Cypher
    .Match("(nodes)")
    .Return(nodes => new {
        NodeEntity = nodes.As<myEntity>(),
        Labels = nodes.Labels()
    }
);
graphClient.Cypher
    .Match("(myEnt1)", "(myEnt2)")
    .Where((myEntity myEnt1) => myEnt1.propID == strID)
    .AndWhere((myEntity myEnt2) => myEnt2.propID == matchAttr)
    .CreateUnique("myEnt1-[:INTOUCHWITH]->myEnt2")
    .ExecuteWithoutResults();
然后,我使用以下代码匹配在Neo4J中创建的所有节点:

strLabel = "(entity:" + strLABEL + " { propID: {newEntity}.propID })";
graphClient.Cypher
    .Merge(strLabel)
    .OnCreate()
    .Set("entity = {newEntity}")
    .WithParams(new { 
        newEntity = new {
            propID = strID,
            propATTR = strATTRIBUTES
        }
    })
    .ExecuteWithoutResults();
var queryNode = graphClient.Cypher
    .Match("(nodes)")
    .Return(nodes => new {
        NodeEntity = nodes.As<myEntity>(),
        Labels = nodes.Labels()
    }
);
graphClient.Cypher
    .Match("(myEnt1)", "(myEnt2)")
    .Where((myEntity myEnt1) => myEnt1.propID == strID)
    .AndWhere((myEntity myEnt2) => myEnt2.propID == matchAttr)
    .CreateUnique("myEnt1-[:INTOUCHWITH]->myEnt2")
    .ExecuteWithoutResults();
当我使用Cypher探索使用该代码填充的数据库时,得到的节点和关系是正确的,Neo4J的执行速度非常快,我测试过的任何查询都是如此。 这非常令人印象深刻,我相信Neo4j在我的行业中有巨大的潜力

但我今天的大问题是填充数据库所需的时间(我的配置:win8 x64、32Go RAM、SSD、intel core i7-3840QM 2.8GHz):

对于小型测试用例(6400行) 创建6373个节点需要13秒,创建7800个关系需要94秒

在真实的测试用例上(40000行) 创建38898个节点需要496秒,创建89532个关系需要3701秒(是的:一个多小时!)

毫无疑问,如此糟糕的性能是由我对neo4jclient缺乏了解直接造成的

如果社区能就如何解决这一瓶颈向我提供建议,那将对我大有帮助

提前谢谢你的帮助

致意
Max

虽然我脑子里没有确切的语法可以为您记录下来,但我建议您在最初读取propATTR值时考虑将其拆分,并将其直接存储为Neo4j中的数组/集合。这将有望使您能够在Neo4j中批量创建关系,而不是在外部迭代节点并执行如此多的顺序事务

后一部分可能类似于:

MATCH (myEnt1),(myEnt2) WHERE myEnt1.propID IN myEnt2.propATTR
CREATE UNIQUE (myEnt1)-[:INTOUCHWITH]->(myEnt2)

抱歉,我的Cypher有点生疏,但重点是尝试将负载完全转移到Neo4j引擎,而不是应用程序逻辑和Neo4j服务器之间的连续往返。我建议,可能是这些往返影响了您的性能,而不是每个事务中涉及的单个工作,因此最大限度地减少事务的数量才是解决问题的方法。

您多久导入一次数据?通常这是一次性的步骤(或很少的时间),而不是人们在考虑性能时通常关注的。如果你在3.7K秒内导入89K个关系,那不是快25/秒了吗?导入时每秒也会创建超过75个节点,对吗?真的那么慢吗?你真的需要经常重复这个过程吗?另一件事是,Neo4j有一个内置的导入器(使用CSV)。您是否尝试过使用它,而不是通过代码逐节点导入?顺便说一下:您的匹配码似乎没有使用标签过滤。首先,非常感谢您的回答。根据产品生命周期步骤的不同,导入数据可以是每天数次(设计阶段)或一次性步骤(操作阶段,移交后)。在当前代码中,我使用节点标签(可能有近200个不同的标签)对它们进行分类:这是一个好的选择还是应该为每个节点添加属性字符串类别?将尝试使用CSV导入并将结果通知您。最后,在导入阶段过滤期间,我没有使用标签,因为我需要匹配所有节点以在它们之间添加rel。