通过Py2neo在Neo4j中建立关系非常缓慢

时间:2018-03-02 02:08:12

标签: pandas neo4j py2neo

我们在数据库中有5种不同类型的节点。最大的一个有~290k,最小的只有~3k。每个节点类型都有一个id字段,它们都被编入索引。我正在使用import capybara import capybara.dsl import unittest class BaseTestCase(unittest.TestCase): def setUp(self): self.page = capybara.dsl.page self.page.visit("http://www.example.com") self.page.click_link("Log in") # ... def tearDown(self): capybara.reset_sessions() class WidgetsTestCase(BaseTestCase): def test_creating_a_widget(self): self.page.click_link("New widget") # ... class WhatsitsTestCase(BaseTestCase): def test_creating_a_whatsit(self): self.page.click_link("New whatsit") # ... 来建立关系,但它非常慢(每秒插入约2个关系)

我使用py2neo从关系csv中读取,迭代每一行以创建包含在事务中的关系。我尝试在一次交易中批量输出10k创建语句,但似乎并没有提高很多速度。

以下是代码:

pandas

有人可以帮我解决我在这里做错了什么。谢谢!

2 个答案:

答案 0 :(得分:1)

您声明有" 5种不同类型的节点" (我将其解释为neo4j术语中的5个节点标签)。此外,您声明他们的id属性已经编入索引。

但是您的f()函数根本没有生成使用标签的Cypher查询,也没有使用id属性。为了利用索引,您的Cypher查询必须指定节点标签和id值。

由于在执行MATCH时目前没有有效的方法来参数化标签,因此以下版本的f()函数会生成具有硬编码标签的Cypher查询(以及硬编码关系类型) ):

def f(label_1, id_1, rel_type, label_2, id_2):
    try:
        tx = graph.begin()
        tx.evaluate(
                'MATCH' +
                '(a:' + label_1 + '{id:$id1}),' +
                '(b:' + label_2 + '{id:$id2}) ' +
                'MERGE (a)-[r:'+rel_type+']->(b)',
            parameters = {'id1': id_1, 'id2': id_2})
        tx.commit()
    except Exception as e:
        print(str(e))

调用f()的代码也必须更改为传递ida的标签名称和b值。希望您的df行将包含该数据(或者您可以获得足够的信息来获取该数据)。

答案 1 :(得分:0)

如果您的目标是获得更好的性能,那么您需要考虑一种不同的模式来加载这些,即批处理。您当前正在为每个关系运行一个Cypher MERGE语句,并在单独的函数调用中将其包装在自己的事务中。

通过查看每个事务或每个函数调用的多个语句来对这些进行批处理将减少网络跃点的数量,并且应该提高性能。