繁体   English   中英

使用neo4jclient的性能问题

[英]performances issues using neo4jclient

我目前正在探索行业中某些过程的图形数据库潜力。 我一周前开始使用Neo4Jclient,所以我不及标准初学者:-)

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

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

StringID=StringLabel(String1,String2,...,StringN);

例如,如果我考虑以下行:

#126=TYPE1(#80,#125);

我想创建一个带有标签“ TYPE1”和2个属性的节点:1)使用ObjectID的唯一ID:上述示例中的“#126” 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();

然后,我使用以下代码匹配在Neo4J中创建的所有节点:

var queryNode = graphClient.Cypher
    .Match("(nodes)")
    .Return(nodes => new {
        NodeEntity = nodes.As<myEntity>(),
        Labels = nodes.Labels()
    }
);

最后,我遍历所有节点,为每个节点拆分propATTR属性,并使用以下代码为在propATTR中找到的每个ObjectID添加一个关系:

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,英特尔酷睿i7-3840QM 2.8GHz):

对于一个小的测试用例(6400行),我花了13秒来创建6373个节点,花了94秒来创建7800个关系

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

毫无疑问,如此糟糕的表现是由于我对neo4jclient知识不足所致。

如果社区可以建议我如何解决该瓶颈,那对我将是巨大的帮助。

在此先感谢您的帮助。

最好的问候马克斯

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

后面的部分可能类似于:

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

抱歉,我的Cypher有点生锈,但是重点是尝试将负载完全转移到Neo4j引擎中,而不是在应用程序逻辑和Neo4j服务器之间进行连续往返。 我建议可能是这些往返行程在损害您的绩效,而不是在每笔交易中影响个人工作,因此减少交易数量将是您的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM