使用neo4jclient进行表演问题

时间:2014-08-29 17:29:51

标签: c# neo4j 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知识很差......) 我决定分3个步骤开展工作:

我从我的文件解析的每一行中提取第一个循环,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,intel core i7-3840QM 2.8GHz):

对于小型测试用例(6400行) 我花了13s创建了6373个节点,94s创建了7800个节点

在一个真实的测试用例(40000行) 它带我496s创建38898个节点,3701s创建89532个关系(是的:超过一个小时!)

毫无疑问,这种糟糕的表现直接源于我糟糕的新知识。

如果社区可以告诉我如何解决这个瓶颈,对我来说将是一个巨大的帮助。

感谢您的帮助。

祝你好运 最大

1 个答案:

答案 0 :(得分:0)

虽然我脑子里没有确切的语法可以为你写下来,但我建议你先看一下你的propATTR值,然后将它们作为数组/集合直接存储在Neo4j中。 。这有望使您能够在Neo4j中批量创建关系,而不是在外部迭代节点并执行如此多的顺序事务。

后一部分可能类似于:

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

抱歉,我的Cypher有点生疏,但重点是尝试将负载完全转移到Neo4j引擎,而不是应用程序逻辑和Neo4j服务器之间的连续往返。我建议这些往返行程可能会影响您的表现,而不是每项交易所涉及的个人工作,所以最大限度地减少交易次数是可行的。