Neo4j:通过CYPHER / REST缓慢创建节点

时间:2015-01-07 14:12:49

标签: rest neo4j cypher

我尝试使用Cypher的MERGE语句通过REST API创建/更新节点。每个节点都具有ca.的属性。 1kb(所有尺寸的总和)。我为每个请求创建/更新1个节点。 (我知道还有其他方法可以批量创建大量节点,但这不是问题。)

我在Windows Server 2008 R2 Enterprise(24个CPU,64GB)上使用Neo4j社区2.1.6,数据库目录驻留在SAN驱动器上。我得到每秒4-6个节点的速率。或者换句话说,单个创建或更新大约需要200毫秒。这对我来说似乎很慢。

查询如下所示:

MERGE (a:TYP1 { name: {name}, version: {version} }) 
SET 
    a.ATTR1={param1},
    a.ATTR2={param2},
    a.ATTR3={param3},
    a.ATTR4={param4},
    a.ATTR5={param5} 
return id(a)

名称,版本和两个属性都有索引。

为什么需要这么长时间?我可以尝试改善这种情况?

我可以想象一个问题是每个请求都必须创建一个新连接?有没有办法让http连接为多个请求保持打开状态?

3 个答案:

答案 0 :(得分:1)

对于查询,我非常确定每个标签每个查询只能使用一个索引,因此根据您的数据,它们的索引使用率可能效率不高。

就持久连接而言,这是可能的,但我认为这取决于您用来连接REST API的库。在ruby neo4j gem中,我们使用具有NetHttpPersistent适配器的Faraday gem。

答案 1 :(得分:1)

  1. 索引仅在您使用MERGE
  2. 的ONE属性时使用
  3. 如果您需要在两者上合并,请创建复合属性,对其进行索引(或更好地使用约束)并合并该复合属性
  4. 使用ON CREATE SET,否则你每次都会(或者 - )写入属性,即使你没有真正创建节点。
  5. 改编声明

    MERGE (a:TYP1 { name_version: {name_version} }) 
    ON CREATE SET 
        a.version = {version}
        a.name = {name}  
        a.ATTR1={param1},
        a.ATTR2={param2},
        a.ATTR3={param3},
        a.ATTR4={param4},
        a.ATTR5={param5} 
    return id(a)
    

答案 2 :(得分:0)

这是一个如何在与Neo4j的一次通信中从nodejs执行一批cypher查询的示例。 要运行它,

的先决条件:

var request=require("request") ;
var graph = require('fbgraph');
graph.setAccessToken(process.argv[2]);

function now() {
    instant = new Date();
    return instant.getHours() 
        +':'+ instant.getMinutes() 
        +':'+ instant.getSeconds()  
        +'.'+ instant.getMilliseconds();
} 

获取Facebook数据:

graph.get('me?fields=groups,friends', function(err,res) {
    if (err) {
        console.log(err);
        throw now() +' Could not get groups from faceBook';
    }

创建密码语句

    var batchCypher = [];
    res.groups.data.forEach(function(group) {
        var singleCypher = {
            "statement" : "CREATE (n:group{group}) RETURN n, id(n)",
            "parameters" : { "group" : group }
        }
        batchCypher.push(singleCypher);

逐一运行

        var fromNow = now();
        request.post({
            uri:"http://localhost:7474/db/data/transaction/commit", 
            json:{statements:singleCypher}
        }, function(err,res) { 
            if (err) {
                console.log('Could not commit '+ group.name);
                throw err;
            }
            console.log('Used '+ fromNow +' - '+ now() +' to commit '+ group.name);
            res.body.results.forEach(function(cypherRes) {
                console.log(cypherRes.data[0].row);
            });
        })
    });

批量运行

    var fromNow = now();
    request.post({
        uri:"http://localhost:7474/db/data/transaction/commit", 
        json:{statements:batchCypher}
    }, function(err,res) { 
        if (err) {
            console.log('Could not commit the batch');
            throw err;
        }
        console.log('Used '+ fromNow +' - '+ now() +' to commit the batch');
    }) 
});

日志显示5个组的事务明显慢于1个组的事务,但明显快于1个组的5个事务。

Used 20:38:16.19 - 20:38:16.77 to commit Voiture occasion Belgique
Used 20:38:16.29 - 20:38:16.82 to commit  Marches & Randonnées
Used 20:38:16.31 - 20:38:16.86 to commit Vlazarus
Used 20:38:16.34 - 20:38:16.87 to commit Wijk voor de fiets
Used 20:38:16.33 - 20:38:16.91 to commit Niet de bestemming maar de route maakt de tocht goed.
Used 20:38:16.35 - 20:38:16.150 to commit the batch

我刚看了你的评论,安德烈亚斯,这不适用于你,但你可以用它来查明时间是花在通讯或更新中